s3-utils: net - Fix one error/usage message
[Samba/gebeck_regimport.git] / source3 / lib / util.c
blob9b9d34c22f4766acd2b3776e756e2f109f3d686d
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "util_tdb.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
30 #include "messages.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
36 #endif
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
52 #if defined(GROUP)
53 #undef GROUP
54 #endif
56 #if defined(GROUP_OBJ)
57 #undef GROUP_OBJ
58 #endif
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
69 enum protocol_types get_Protocol(void)
71 return Protocol;
74 void set_Protocol(enum protocol_types p)
76 Protocol = p;
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
83 gfree_names();
84 gfree_loadparm();
85 gfree_charcnv();
86 gfree_interfaces();
87 gfree_debugsyms();
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95 bool fake_dir_create_times)
97 SMB_STRUCT_STAT st;
98 if (!sbuf)
99 sbuf = &st;
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
102 return(False);
104 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname)
113 SMB_STRUCT_STAT st;
114 if (sys_stat(fname, &st, false) != 0)
115 return(False);
117 return S_ISSOCK(st.st_ex_mode);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
126 return sbuf->st_ex_size;
129 /*******************************************************************
130 Returns the size in bytes of the named file.
131 ********************************************************************/
133 SMB_OFF_T get_file_size(char *file_name)
135 SMB_STRUCT_STAT buf;
136 buf.st_ex_size = 0;
137 if (sys_stat(file_name, &buf, false) != 0)
138 return (SMB_OFF_T)-1;
139 return get_file_size_stat(&buf);
142 /*******************************************************************
143 Show a smb message structure.
144 ********************************************************************/
146 void show_msg(const char *buf)
148 int i;
149 int bcc=0;
151 if (!DEBUGLVL(5))
152 return;
154 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
155 smb_len(buf),
156 (int)CVAL(buf,smb_com),
157 (int)CVAL(buf,smb_rcls),
158 (int)CVAL(buf,smb_reh),
159 (int)SVAL(buf,smb_err),
160 (int)CVAL(buf,smb_flg),
161 (int)SVAL(buf,smb_flg2)));
162 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
163 (int)SVAL(buf,smb_tid),
164 (int)SVAL(buf,smb_pid),
165 (int)SVAL(buf,smb_uid),
166 (int)SVAL(buf,smb_mid)));
167 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
169 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
170 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
171 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
173 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
175 DEBUGADD(5,("smb_bcc=%d\n",bcc));
177 if (DEBUGLEVEL < 10)
178 return;
180 if (DEBUGLEVEL < 50)
181 bcc = MIN(bcc, 512);
183 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
186 /*******************************************************************
187 Setup only the byte count for a smb message.
188 ********************************************************************/
190 int set_message_bcc(char *buf,int num_bytes)
192 int num_words = CVAL(buf,smb_wct);
193 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
194 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
195 return (smb_size + num_words*2 + num_bytes);
198 /*******************************************************************
199 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
200 Return the bytes added
201 ********************************************************************/
203 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
205 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
206 uint8 *tmp;
208 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
209 DEBUG(0, ("talloc failed\n"));
210 return -1;
212 *outbuf = tmp;
214 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
215 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
216 return blob.length;
219 /*******************************************************************
220 Reduce a file name, removing .. elements.
221 ********************************************************************/
223 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
225 char *p = NULL;
226 char *str = NULL;
228 DEBUG(3,("dos_clean_name [%s]\n",s));
230 /* remove any double slashes */
231 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
232 if (!str) {
233 return NULL;
236 /* Remove leading .\\ characters */
237 if(strncmp(str, ".\\", 2) == 0) {
238 trim_string(str, ".\\", NULL);
239 if(*str == 0) {
240 str = talloc_strdup(ctx, ".\\");
241 if (!str) {
242 return NULL;
247 while ((p = strstr_m(str,"\\..\\")) != NULL) {
248 char *s1;
250 *p = 0;
251 s1 = p+3;
253 if ((p=strrchr_m(str,'\\')) != NULL) {
254 *p = 0;
255 } else {
256 *str = 0;
258 str = talloc_asprintf(ctx,
259 "%s%s",
260 str,
261 s1);
262 if (!str) {
263 return NULL;
267 trim_string(str,NULL,"\\..");
268 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
271 /*******************************************************************
272 Reduce a file name, removing .. elements.
273 ********************************************************************/
275 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
277 char *p = NULL;
278 char *str = NULL;
280 DEBUG(3,("unix_clean_name [%s]\n",s));
282 /* remove any double slashes */
283 str = talloc_all_string_sub(ctx, s, "//","/");
284 if (!str) {
285 return NULL;
288 /* Remove leading ./ characters */
289 if(strncmp(str, "./", 2) == 0) {
290 trim_string(str, "./", NULL);
291 if(*str == 0) {
292 str = talloc_strdup(ctx, "./");
293 if (!str) {
294 return NULL;
299 while ((p = strstr_m(str,"/../")) != NULL) {
300 char *s1;
302 *p = 0;
303 s1 = p+3;
305 if ((p=strrchr_m(str,'/')) != NULL) {
306 *p = 0;
307 } else {
308 *str = 0;
310 str = talloc_asprintf(ctx,
311 "%s%s",
312 str,
313 s1);
314 if (!str) {
315 return NULL;
319 trim_string(str,NULL,"/..");
320 return talloc_all_string_sub(ctx, str, "/./", "/");
323 char *clean_name(TALLOC_CTX *ctx, const char *s)
325 char *str = dos_clean_name(ctx, s);
326 if (!str) {
327 return NULL;
329 return unix_clean_name(ctx, str);
332 /*******************************************************************
333 Write data into an fd at a given offset. Ignore seek errors.
334 ********************************************************************/
336 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
338 size_t total=0;
339 ssize_t ret;
341 if (pos == (SMB_OFF_T)-1) {
342 return write_data(fd, buffer, N);
344 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
345 while (total < N) {
346 ret = sys_pwrite(fd,buffer + total,N - total, pos);
347 if (ret == -1 && errno == ESPIPE) {
348 return write_data(fd, buffer + total,N - total);
350 if (ret == -1) {
351 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
352 return -1;
354 if (ret == 0) {
355 return total;
357 total += ret;
358 pos += ret;
360 return (ssize_t)total;
361 #else
362 /* Use lseek and write_data. */
363 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
364 if (errno != ESPIPE) {
365 return -1;
368 return write_data(fd, buffer, N);
369 #endif
373 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
374 struct event_context *ev_ctx,
375 struct server_id id,
376 bool parent_longlived)
378 NTSTATUS status = NT_STATUS_OK;
380 /* Reset the state of the random
381 * number generation system, so
382 * children do not get the same random
383 * numbers as each other */
384 set_need_random_reseed();
386 /* tdb needs special fork handling */
387 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
388 DEBUG(0,("tdb_reopen_all failed.\n"));
389 status = NT_STATUS_OPEN_FAILED;
390 goto done;
393 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
394 smb_panic(__location__ ": Failed to re-initialise event context");
397 if (msg_ctx) {
399 * For clustering, we need to re-init our ctdbd connection after the
400 * fork
402 status = messaging_reinit(msg_ctx, id);
403 if (!NT_STATUS_IS_OK(status)) {
404 DEBUG(0,("messaging_reinit() failed: %s\n",
405 nt_errstr(status)));
408 done:
409 return status;
412 /****************************************************************************
413 (Hopefully) efficient array append.
414 ****************************************************************************/
416 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
417 void *element, void *_array, uint32 *num_elements,
418 ssize_t *array_size)
420 void **array = (void **)_array;
422 if (*array_size < 0) {
423 return;
426 if (*array == NULL) {
427 if (*array_size == 0) {
428 *array_size = 128;
431 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
432 goto error;
435 *array = TALLOC(mem_ctx, element_size * (*array_size));
436 if (*array == NULL) {
437 goto error;
441 if (*num_elements == *array_size) {
442 *array_size *= 2;
444 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
445 goto error;
448 *array = TALLOC_REALLOC(mem_ctx, *array,
449 element_size * (*array_size));
451 if (*array == NULL) {
452 goto error;
456 memcpy((char *)(*array) + element_size*(*num_elements),
457 element, element_size);
458 *num_elements += 1;
460 return;
462 error:
463 *num_elements = 0;
464 *array_size = -1;
467 /****************************************************************************
468 Get my own domain name, or "" if we have none.
469 ****************************************************************************/
471 char *get_mydnsdomname(TALLOC_CTX *ctx)
473 const char *domname;
474 char *p;
476 domname = get_mydnsfullname();
477 if (!domname) {
478 return NULL;
481 p = strchr_m(domname, '.');
482 if (p) {
483 p++;
484 return talloc_strdup(ctx, p);
485 } else {
486 return talloc_strdup(ctx, "");
490 /****************************************************************************
491 Interpret a protocol description string, with a default.
492 ****************************************************************************/
494 int interpret_protocol(const char *str,int def)
496 if (strequal(str,"NT1"))
497 return(PROTOCOL_NT1);
498 if (strequal(str,"LANMAN2"))
499 return(PROTOCOL_LANMAN2);
500 if (strequal(str,"LANMAN1"))
501 return(PROTOCOL_LANMAN1);
502 if (strequal(str,"CORE"))
503 return(PROTOCOL_CORE);
504 if (strequal(str,"COREPLUS"))
505 return(PROTOCOL_COREPLUS);
506 if (strequal(str,"CORE+"))
507 return(PROTOCOL_COREPLUS);
509 DEBUG(0,("Unrecognised protocol level %s\n",str));
511 return(def);
515 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
516 /******************************************************************
517 Remove any mount options such as -rsize=2048,wsize=2048 etc.
518 Based on a fix from <Thomas.Hepper@icem.de>.
519 Returns a malloc'ed string.
520 *******************************************************************/
522 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
524 if (*str == '-') {
525 const char *p = str;
526 while(*p && !isspace(*p))
527 p++;
528 while(*p && isspace(*p))
529 p++;
530 if(*p) {
531 return talloc_strdup(ctx, p);
534 return NULL;
537 /*******************************************************************
538 Patch from jkf@soton.ac.uk
539 Split Luke's automount_server into YP lookup and string splitter
540 so can easily implement automount_path().
541 Returns a malloc'ed string.
542 *******************************************************************/
544 #ifdef WITH_NISPLUS_HOME
545 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
547 char *value = NULL;
549 char *nis_map = (char *)lp_nis_home_map_name();
551 char buffer[NIS_MAXATTRVAL + 1];
552 nis_result *result;
553 nis_object *object;
554 entry_obj *entry;
556 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
557 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
559 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
560 if (result->status != NIS_SUCCESS) {
561 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
562 } else {
563 object = result->objects.objects_val;
564 if (object->zo_data.zo_type == ENTRY_OBJ) {
565 entry = &object->zo_data.objdata_u.en_data;
566 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
567 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
569 value = talloc_strdup(ctx,
570 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
571 if (!value) {
572 nis_freeresult(result);
573 return NULL;
575 value = talloc_string_sub(ctx,
576 value,
577 "&",
578 user_name);
582 nis_freeresult(result);
584 if (value) {
585 value = strip_mount_options(ctx, value);
586 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
587 user_name, value));
589 return value;
591 #else /* WITH_NISPLUS_HOME */
593 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
595 char *value = NULL;
597 int nis_error; /* returned by yp all functions */
598 char *nis_result; /* yp_match inits this */
599 int nis_result_len; /* and set this */
600 char *nis_domain; /* yp_get_default_domain inits this */
601 char *nis_map = (char *)lp_nis_home_map_name();
603 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
604 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
605 return NULL;
608 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
610 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
611 strlen(user_name), &nis_result,
612 &nis_result_len)) == 0) {
613 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
614 nis_result[nis_result_len] = '\0';
616 value = talloc_strdup(ctx, nis_result);
617 if (!value) {
618 return NULL;
620 value = strip_mount_options(ctx, value);
621 } else if(nis_error == YPERR_KEY) {
622 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
623 user_name, nis_map));
624 DEBUG(3, ("using defaults for server and home directory\n"));
625 } else {
626 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
627 yperr_string(nis_error), user_name, nis_map));
630 if (value) {
631 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
633 return value;
635 #endif /* WITH_NISPLUS_HOME */
636 #endif
638 /****************************************************************************
639 Check if a process exists. Does this work on all unixes?
640 ****************************************************************************/
642 bool process_exists(const struct server_id pid)
644 if (procid_is_me(&pid)) {
645 return True;
648 if (procid_is_local(&pid)) {
649 return (kill(pid.pid,0) == 0 || errno != ESRCH);
652 #ifdef CLUSTER_SUPPORT
653 return ctdbd_process_exists(messaging_ctdbd_connection(),
654 pid.vnn, pid.pid);
655 #else
656 return False;
657 #endif
660 bool processes_exist(const struct server_id *pids, int num_pids,
661 bool *results)
663 struct server_id *remote_pids = NULL;
664 int *remote_idx = NULL;
665 bool *remote_results = NULL;
666 int i, num_remote_pids;
667 bool result = false;
669 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
670 if (remote_pids == NULL) {
671 goto fail;
673 remote_idx = talloc_array(talloc_tos(), int, num_pids);
674 if (remote_idx == NULL) {
675 goto fail;
677 remote_results = talloc_array(talloc_tos(), bool, num_pids);
678 if (remote_results == NULL) {
679 goto fail;
682 num_remote_pids = 0;
684 for (i=0; i<num_pids; i++) {
685 if (procid_is_me(&pids[i])) {
686 results[i] = true;
687 continue;
689 if (procid_is_local(&pids[i])) {
690 results[i] = ((kill(pids[i].pid,0) == 0) ||
691 (errno != ESRCH));
692 continue;
695 remote_pids[num_remote_pids] = pids[i];
696 remote_idx[num_remote_pids] = i;
697 num_remote_pids += 1;
700 if (num_remote_pids != 0) {
701 #ifdef CLUSTER_SUPPORT
702 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
703 remote_pids, num_remote_pids,
704 remote_results)) {
705 goto fail;
707 #else
708 for (i=0; i<num_remote_pids; i++) {
709 remote_results[i] = false;
711 #endif
713 for (i=0; i<num_remote_pids; i++) {
714 results[remote_idx[i]] = remote_results[i];
718 result = true;
719 fail:
720 TALLOC_FREE(remote_results);
721 TALLOC_FREE(remote_idx);
722 TALLOC_FREE(remote_pids);
723 return result;
726 /*******************************************************************
727 Convert a uid into a user name.
728 ********************************************************************/
730 const char *uidtoname(uid_t uid)
732 TALLOC_CTX *ctx = talloc_tos();
733 char *name = NULL;
734 struct passwd *pass = NULL;
736 pass = getpwuid_alloc(ctx,uid);
737 if (pass) {
738 name = talloc_strdup(ctx,pass->pw_name);
739 TALLOC_FREE(pass);
740 } else {
741 name = talloc_asprintf(ctx,
742 "%ld",
743 (long int)uid);
745 return name;
748 /*******************************************************************
749 Convert a gid into a group name.
750 ********************************************************************/
752 char *gidtoname(gid_t gid)
754 struct group *grp;
756 grp = getgrgid(gid);
757 if (grp) {
758 return talloc_strdup(talloc_tos(), grp->gr_name);
760 else {
761 return talloc_asprintf(talloc_tos(),
762 "%d",
763 (int)gid);
767 /*******************************************************************
768 Convert a user name into a uid.
769 ********************************************************************/
771 uid_t nametouid(const char *name)
773 struct passwd *pass;
774 char *p;
775 uid_t u;
777 pass = Get_Pwnam_alloc(talloc_tos(), name);
778 if (pass) {
779 u = pass->pw_uid;
780 TALLOC_FREE(pass);
781 return u;
784 u = (uid_t)strtol(name, &p, 0);
785 if ((p != name) && (*p == '\0'))
786 return u;
788 return (uid_t)-1;
791 /*******************************************************************
792 Convert a name to a gid_t if possible. Return -1 if not a group.
793 ********************************************************************/
795 gid_t nametogid(const char *name)
797 struct group *grp;
798 char *p;
799 gid_t g;
801 g = (gid_t)strtol(name, &p, 0);
802 if ((p != name) && (*p == '\0'))
803 return g;
805 grp = sys_getgrnam(name);
806 if (grp)
807 return(grp->gr_gid);
808 return (gid_t)-1;
811 /*******************************************************************
812 Something really nasty happened - panic !
813 ********************************************************************/
815 void smb_panic_s3(const char *why)
817 char *cmd;
818 int result;
820 DEBUG(0,("PANIC (pid %llu): %s\n",
821 (unsigned long long)sys_getpid(), why));
822 log_stack_trace();
824 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
826 * Make sure all children can attach a debugger.
828 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
829 #endif
831 cmd = lp_panic_action();
832 if (cmd && *cmd) {
833 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
834 result = system(cmd);
836 if (result == -1)
837 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
838 strerror(errno)));
839 else
840 DEBUG(0, ("smb_panic(): action returned status %d\n",
841 WEXITSTATUS(result)));
844 dump_core();
847 /*******************************************************************
848 Print a backtrace of the stack to the debug log. This function
849 DELIBERATELY LEAKS MEMORY. The expectation is that you should
850 exit shortly after calling it.
851 ********************************************************************/
853 #ifdef HAVE_LIBUNWIND_H
854 #include <libunwind.h>
855 #endif
857 #ifdef HAVE_EXECINFO_H
858 #include <execinfo.h>
859 #endif
861 #ifdef HAVE_LIBEXC_H
862 #include <libexc.h>
863 #endif
865 void log_stack_trace(void)
867 #ifdef HAVE_LIBUNWIND
868 /* Try to use libunwind before any other technique since on ia64
869 * libunwind correctly walks the stack in more circumstances than
870 * backtrace.
872 unw_cursor_t cursor;
873 unw_context_t uc;
874 unsigned i = 0;
876 char procname[256];
877 unw_word_t ip, sp, off;
879 procname[sizeof(procname) - 1] = '\0';
881 if (unw_getcontext(&uc) != 0) {
882 goto libunwind_failed;
885 if (unw_init_local(&cursor, &uc) != 0) {
886 goto libunwind_failed;
889 DEBUG(0, ("BACKTRACE:\n"));
891 do {
892 ip = sp = 0;
893 unw_get_reg(&cursor, UNW_REG_IP, &ip);
894 unw_get_reg(&cursor, UNW_REG_SP, &sp);
896 switch (unw_get_proc_name(&cursor,
897 procname, sizeof(procname) - 1, &off) ) {
898 case 0:
899 /* Name found. */
900 case -UNW_ENOMEM:
901 /* Name truncated. */
902 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
903 i, procname, (long long)off,
904 (long long)ip, (long long) sp));
905 break;
906 default:
907 /* case -UNW_ENOINFO: */
908 /* case -UNW_EUNSPEC: */
909 /* No symbol name found. */
910 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
911 i, "<unknown symbol>",
912 (long long)ip, (long long) sp));
914 ++i;
915 } while (unw_step(&cursor) > 0);
917 return;
919 libunwind_failed:
920 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
922 #elif HAVE_BACKTRACE_SYMBOLS
923 void *backtrace_stack[BACKTRACE_STACK_SIZE];
924 size_t backtrace_size;
925 char **backtrace_strings;
927 /* get the backtrace (stack frames) */
928 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
929 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
931 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
932 (unsigned long)backtrace_size));
934 if (backtrace_strings) {
935 int i;
937 for (i = 0; i < backtrace_size; i++)
938 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
940 /* Leak the backtrace_strings, rather than risk what free() might do */
943 #elif HAVE_LIBEXC
945 /* The IRIX libexc library provides an API for unwinding the stack. See
946 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
947 * since we are about to abort anyway, it hardly matters.
950 #define NAMESIZE 32 /* Arbitrary */
952 __uint64_t addrs[BACKTRACE_STACK_SIZE];
953 char * names[BACKTRACE_STACK_SIZE];
954 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
956 int i;
957 int levels;
959 ZERO_ARRAY(addrs);
960 ZERO_ARRAY(names);
961 ZERO_ARRAY(namebuf);
963 /* We need to be root so we can open our /proc entry to walk
964 * our stack. It also helps when we want to dump core.
966 become_root();
968 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
969 names[i] = namebuf + (i * NAMESIZE);
972 levels = trace_back_stack(0, addrs, names,
973 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
975 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
976 for (i = 0; i < levels; i++) {
977 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
979 #undef NAMESIZE
981 #else
982 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
983 #endif
986 /*******************************************************************
987 A readdir wrapper which just returns the file name.
988 ********************************************************************/
990 const char *readdirname(SMB_STRUCT_DIR *p)
992 SMB_STRUCT_DIRENT *ptr;
993 char *dname;
995 if (!p)
996 return(NULL);
998 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
999 if (!ptr)
1000 return(NULL);
1002 dname = ptr->d_name;
1004 #ifdef NEXT2
1005 if (telldir(p) < 0)
1006 return(NULL);
1007 #endif
1009 #ifdef HAVE_BROKEN_READDIR_NAME
1010 /* using /usr/ucb/cc is BAD */
1011 dname = dname - 2;
1012 #endif
1014 return talloc_strdup(talloc_tos(), dname);
1017 /*******************************************************************
1018 Utility function used to decide if the last component
1019 of a path matches a (possibly wildcarded) entry in a namelist.
1020 ********************************************************************/
1022 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1024 const char *last_component;
1026 /* if we have no list it's obviously not in the path */
1027 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1028 return False;
1031 DEBUG(8, ("is_in_path: %s\n", name));
1033 /* Get the last component of the unix name. */
1034 last_component = strrchr_m(name, '/');
1035 if (!last_component) {
1036 last_component = name;
1037 } else {
1038 last_component++; /* Go past '/' */
1041 for(; namelist->name != NULL; namelist++) {
1042 if(namelist->is_wild) {
1043 if (mask_match(last_component, namelist->name, case_sensitive)) {
1044 DEBUG(8,("is_in_path: mask match succeeded\n"));
1045 return True;
1047 } else {
1048 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1049 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1050 DEBUG(8,("is_in_path: match succeeded\n"));
1051 return True;
1055 DEBUG(8,("is_in_path: match not found\n"));
1056 return False;
1059 /*******************************************************************
1060 Strip a '/' separated list into an array of
1061 name_compare_enties structures suitable for
1062 passing to is_in_path(). We do this for
1063 speed so we can pre-parse all the names in the list
1064 and don't do it for each call to is_in_path().
1065 We also check if the entry contains a wildcard to
1066 remove a potentially expensive call to mask_match
1067 if possible.
1068 ********************************************************************/
1070 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1072 char *name_end;
1073 char *namelist;
1074 char *nameptr;
1075 int num_entries = 0;
1076 int i;
1078 (*ppname_array) = NULL;
1080 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1081 return;
1083 namelist = talloc_strdup(talloc_tos(), namelist_in);
1084 if (namelist == NULL) {
1085 DEBUG(0,("set_namearray: talloc fail\n"));
1086 return;
1088 nameptr = namelist;
1090 /* We need to make two passes over the string. The
1091 first to count the number of elements, the second
1092 to split it.
1095 while(*nameptr) {
1096 if ( *nameptr == '/' ) {
1097 /* cope with multiple (useless) /s) */
1098 nameptr++;
1099 continue;
1101 /* anything left? */
1102 if ( *nameptr == '\0' )
1103 break;
1105 /* find the next '/' or consume remaining */
1106 name_end = strchr_m(nameptr, '/');
1107 if (name_end == NULL)
1108 name_end = (char *)nameptr + strlen(nameptr);
1110 /* next segment please */
1111 nameptr = name_end + 1;
1112 num_entries++;
1115 if(num_entries == 0) {
1116 talloc_free(namelist);
1117 return;
1120 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1121 DEBUG(0,("set_namearray: malloc fail\n"));
1122 talloc_free(namelist);
1123 return;
1126 /* Now copy out the names */
1127 nameptr = namelist;
1128 i = 0;
1129 while(*nameptr) {
1130 if ( *nameptr == '/' ) {
1131 /* cope with multiple (useless) /s) */
1132 nameptr++;
1133 continue;
1135 /* anything left? */
1136 if ( *nameptr == '\0' )
1137 break;
1139 /* find the next '/' or consume remaining */
1140 name_end = strchr_m(nameptr, '/');
1141 if (name_end)
1142 *name_end = '\0';
1143 else
1144 name_end = nameptr + strlen(nameptr);
1146 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1147 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1148 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1149 talloc_free(namelist);
1150 return;
1153 /* next segment please */
1154 nameptr = name_end + 1;
1155 i++;
1158 (*ppname_array)[i].name = NULL;
1160 talloc_free(namelist);
1161 return;
1164 #undef DBGC_CLASS
1165 #define DBGC_CLASS DBGC_LOCKING
1167 /****************************************************************************
1168 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1169 is dealt with in posix.c
1170 Returns True if we have information regarding this lock region (and returns
1171 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1172 ****************************************************************************/
1174 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1176 SMB_STRUCT_FLOCK lock;
1177 int ret;
1179 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1180 fd,(double)*poffset,(double)*pcount,*ptype));
1182 lock.l_type = *ptype;
1183 lock.l_whence = SEEK_SET;
1184 lock.l_start = *poffset;
1185 lock.l_len = *pcount;
1186 lock.l_pid = 0;
1188 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1190 if (ret == -1) {
1191 int sav = errno;
1192 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1193 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1194 errno = sav;
1195 return False;
1198 *ptype = lock.l_type;
1199 *poffset = lock.l_start;
1200 *pcount = lock.l_len;
1201 *ppid = lock.l_pid;
1203 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1204 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1205 return True;
1208 #undef DBGC_CLASS
1209 #define DBGC_CLASS DBGC_ALL
1211 /*******************************************************************
1212 Is the name specified one of my netbios names.
1213 Returns true if it is equal, false otherwise.
1214 ********************************************************************/
1216 bool is_myname(const char *s)
1218 int n;
1219 bool ret = False;
1221 for (n=0; my_netbios_names(n); n++) {
1222 if (strequal(my_netbios_names(n), s)) {
1223 ret=True;
1224 break;
1227 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1228 return(ret);
1231 /*******************************************************************
1232 Is the name specified our workgroup/domain.
1233 Returns true if it is equal, false otherwise.
1234 ********************************************************************/
1236 bool is_myworkgroup(const char *s)
1238 bool ret = False;
1240 if (strequal(s, lp_workgroup())) {
1241 ret=True;
1244 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1245 return(ret);
1248 /*******************************************************************
1249 we distinguish between 2K and XP by the "Native Lan Manager" string
1250 WinXP => "Windows 2002 5.1"
1251 WinXP 64bit => "Windows XP 5.2"
1252 Win2k => "Windows 2000 5.0"
1253 NT4 => "Windows NT 4.0"
1254 Win9x => "Windows 4.0"
1255 Windows 2003 doesn't set the native lan manager string but
1256 they do set the domain to "Windows 2003 5.2" (probably a bug).
1257 ********************************************************************/
1259 void ra_lanman_string( const char *native_lanman )
1261 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1262 set_remote_arch( RA_WINXP );
1263 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1264 set_remote_arch( RA_WINXP64 );
1265 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1266 set_remote_arch( RA_WIN2K3 );
1269 static const char *remote_arch_str;
1271 const char *get_remote_arch_str(void)
1273 if (!remote_arch_str) {
1274 return "UNKNOWN";
1276 return remote_arch_str;
1279 /*******************************************************************
1280 Set the horrid remote_arch string based on an enum.
1281 ********************************************************************/
1283 void set_remote_arch(enum remote_arch_types type)
1285 ra_type = type;
1286 switch( type ) {
1287 case RA_WFWG:
1288 remote_arch_str = "WfWg";
1289 break;
1290 case RA_OS2:
1291 remote_arch_str = "OS2";
1292 break;
1293 case RA_WIN95:
1294 remote_arch_str = "Win95";
1295 break;
1296 case RA_WINNT:
1297 remote_arch_str = "WinNT";
1298 break;
1299 case RA_WIN2K:
1300 remote_arch_str = "Win2K";
1301 break;
1302 case RA_WINXP:
1303 remote_arch_str = "WinXP";
1304 break;
1305 case RA_WINXP64:
1306 remote_arch_str = "WinXP64";
1307 break;
1308 case RA_WIN2K3:
1309 remote_arch_str = "Win2K3";
1310 break;
1311 case RA_VISTA:
1312 remote_arch_str = "Vista";
1313 break;
1314 case RA_SAMBA:
1315 remote_arch_str = "Samba";
1316 break;
1317 case RA_CIFSFS:
1318 remote_arch_str = "CIFSFS";
1319 break;
1320 case RA_OSX:
1321 remote_arch_str = "OSX";
1322 break;
1323 default:
1324 ra_type = RA_UNKNOWN;
1325 remote_arch_str = "UNKNOWN";
1326 break;
1329 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1330 remote_arch_str));
1333 /*******************************************************************
1334 Get the remote_arch type.
1335 ********************************************************************/
1337 enum remote_arch_types get_remote_arch(void)
1339 return ra_type;
1342 const char *tab_depth(int level, int depth)
1344 if( CHECK_DEBUGLVL(level) ) {
1345 dbgtext("%*s", depth*4, "");
1347 return "";
1350 /*****************************************************************************
1351 Provide a checksum on a string
1353 Input: s - the null-terminated character string for which the checksum
1354 will be calculated.
1356 Output: The checksum value calculated for s.
1357 *****************************************************************************/
1359 int str_checksum(const char *s)
1361 if (s == NULL)
1362 return 0;
1363 return hash(s, strlen(s), 0);
1366 /*****************************************************************
1367 Zero a memory area then free it. Used to catch bugs faster.
1368 *****************************************************************/
1370 void zero_free(void *p, size_t size)
1372 memset(p, 0, size);
1373 SAFE_FREE(p);
1376 /*****************************************************************
1377 Set our open file limit to a requested max and return the limit.
1378 *****************************************************************/
1380 int set_maxfiles(int requested_max)
1382 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1383 struct rlimit rlp;
1384 int saved_current_limit;
1386 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1387 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1388 strerror(errno) ));
1389 /* just guess... */
1390 return requested_max;
1394 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1395 * account for the extra fd we need
1396 * as well as the log files and standard
1397 * handles etc. Save the limit we want to set in case
1398 * we are running on an OS that doesn't support this limit (AIX)
1399 * which always returns RLIM_INFINITY for rlp.rlim_max.
1402 /* Try raising the hard (max) limit to the requested amount. */
1404 #if defined(RLIM_INFINITY)
1405 if (rlp.rlim_max != RLIM_INFINITY) {
1406 int orig_max = rlp.rlim_max;
1408 if ( rlp.rlim_max < requested_max )
1409 rlp.rlim_max = requested_max;
1411 /* This failing is not an error - many systems (Linux) don't
1412 support our default request of 10,000 open files. JRA. */
1414 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1415 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1416 (int)rlp.rlim_max, strerror(errno) ));
1418 /* Set failed - restore original value from get. */
1419 rlp.rlim_max = orig_max;
1422 #endif
1424 /* Now try setting the soft (current) limit. */
1426 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1428 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1429 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1430 (int)rlp.rlim_cur, strerror(errno) ));
1431 /* just guess... */
1432 return saved_current_limit;
1435 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1436 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1437 strerror(errno) ));
1438 /* just guess... */
1439 return saved_current_limit;
1442 #if defined(RLIM_INFINITY)
1443 if(rlp.rlim_cur == RLIM_INFINITY)
1444 return saved_current_limit;
1445 #endif
1447 if((int)rlp.rlim_cur > saved_current_limit)
1448 return saved_current_limit;
1450 return rlp.rlim_cur;
1451 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1453 * No way to know - just guess...
1455 return requested_max;
1456 #endif
1459 /*****************************************************************
1460 malloc that aborts with smb_panic on fail or zero size.
1461 *****************************************************************/
1463 void *smb_xmalloc_array(size_t size, unsigned int count)
1465 void *p;
1466 if (size == 0) {
1467 smb_panic("smb_xmalloc_array: called with zero size");
1469 if (count >= MAX_ALLOC_SIZE/size) {
1470 smb_panic("smb_xmalloc_array: alloc size too large");
1472 if ((p = SMB_MALLOC(size*count)) == NULL) {
1473 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1474 (unsigned long)size, (unsigned long)count));
1475 smb_panic("smb_xmalloc_array: malloc failed");
1477 return p;
1481 vasprintf that aborts on malloc fail
1484 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1486 int n;
1487 va_list ap2;
1489 va_copy(ap2, ap);
1491 n = vasprintf(ptr, format, ap2);
1492 va_end(ap2);
1493 if (n == -1 || ! *ptr) {
1494 smb_panic("smb_xvasprintf: out of memory");
1496 return n;
1499 /*****************************************************************
1500 Get local hostname and cache result.
1501 *****************************************************************/
1503 char *myhostname(void)
1505 static char *ret;
1506 if (ret == NULL) {
1507 ret = get_myname(NULL);
1509 return ret;
1512 /*****************************************************************
1513 Get local hostname and cache result.
1514 *****************************************************************/
1516 char *myhostname_upper(void)
1518 char *name;
1519 static char *ret;
1520 if (ret == NULL) {
1521 name = get_myname(talloc_tos());
1522 ret = strupper_talloc(NULL, name);
1523 talloc_free(name);
1525 return ret;
1529 * @brief Returns an absolute path to a file concatenating the provided
1530 * @a rootpath and @a basename
1532 * @param name Filename, relative to @a rootpath
1534 * @retval Pointer to a string containing the full path.
1537 static char *xx_path(const char *name, const char *rootpath)
1539 char *fname = NULL;
1541 fname = talloc_strdup(talloc_tos(), rootpath);
1542 if (!fname) {
1543 return NULL;
1545 trim_string(fname,"","/");
1547 if (!directory_exist(fname)) {
1548 if (!mkdir(fname,0755))
1549 DEBUG(1, ("Unable to create directory %s for file %s. "
1550 "Error was %s\n", fname, name, strerror(errno)));
1553 return talloc_asprintf(talloc_tos(),
1554 "%s/%s",
1555 fname,
1556 name);
1560 * @brief Returns an absolute path to a file in the Samba lock directory.
1562 * @param name File to find, relative to LOCKDIR.
1564 * @retval Pointer to a talloc'ed string containing the full path.
1567 char *lock_path(const char *name)
1569 return xx_path(name, lp_lockdir());
1573 * @brief Returns an absolute path to a file in the Samba pid directory.
1575 * @param name File to find, relative to PIDDIR.
1577 * @retval Pointer to a talloc'ed string containing the full path.
1580 char *pid_path(const char *name)
1582 return xx_path(name, lp_piddir());
1586 * @brief Returns an absolute path to a file in the Samba state directory.
1588 * @param name File to find, relative to STATEDIR.
1590 * @retval Pointer to a talloc'ed string containing the full path.
1593 char *state_path(const char *name)
1595 return xx_path(name, lp_statedir());
1599 * @brief Returns an absolute path to a file in the Samba cache directory.
1601 * @param name File to find, relative to CACHEDIR.
1603 * @retval Pointer to a talloc'ed string containing the full path.
1606 char *cache_path(const char *name)
1608 return xx_path(name, lp_cachedir());
1611 /*******************************************************************
1612 Given a filename - get its directory name
1613 ********************************************************************/
1615 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1616 const char **name)
1618 char *p;
1619 ptrdiff_t len;
1621 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1623 if (p == NULL) {
1624 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1625 return False;
1627 if (name) {
1628 *name = dir;
1630 return True;
1633 len = p-dir;
1635 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1636 return False;
1638 (*parent)[len] = '\0';
1640 if (name) {
1641 *name = p+1;
1643 return True;
1646 /*******************************************************************
1647 Determine if a pattern contains any Microsoft wildcard characters.
1648 *******************************************************************/
1650 bool ms_has_wild(const char *s)
1652 char c;
1654 if (lp_posix_pathnames()) {
1655 /* With posix pathnames no characters are wild. */
1656 return False;
1659 while ((c = *s++)) {
1660 switch (c) {
1661 case '*':
1662 case '?':
1663 case '<':
1664 case '>':
1665 case '"':
1666 return True;
1669 return False;
1672 bool ms_has_wild_w(const smb_ucs2_t *s)
1674 smb_ucs2_t c;
1675 if (!s) return False;
1676 while ((c = *s++)) {
1677 switch (c) {
1678 case UCS2_CHAR('*'):
1679 case UCS2_CHAR('?'):
1680 case UCS2_CHAR('<'):
1681 case UCS2_CHAR('>'):
1682 case UCS2_CHAR('"'):
1683 return True;
1686 return False;
1689 /*******************************************************************
1690 A wrapper that handles case sensitivity and the special handling
1691 of the ".." name.
1692 *******************************************************************/
1694 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1696 if (ISDOTDOT(string))
1697 string = ".";
1698 if (ISDOT(pattern))
1699 return False;
1701 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1704 /*******************************************************************
1705 A wrapper that handles case sensitivity and the special handling
1706 of the ".." name. Varient that is only called by old search code which requires
1707 pattern translation.
1708 *******************************************************************/
1710 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1712 if (ISDOTDOT(string))
1713 string = ".";
1714 if (ISDOT(pattern))
1715 return False;
1717 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1720 /*******************************************************************
1721 A wrapper that handles a list of patters and calls mask_match()
1722 on each. Returns True if any of the patterns match.
1723 *******************************************************************/
1725 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1727 while (listLen-- > 0) {
1728 if (mask_match(string, *list++, is_case_sensitive))
1729 return True;
1731 return False;
1734 /*********************************************************
1735 Recursive routine that is called by unix_wild_match.
1736 *********************************************************/
1738 static bool unix_do_match(const char *regexp, const char *str)
1740 const char *p;
1742 for( p = regexp; *p && *str; ) {
1744 switch(*p) {
1745 case '?':
1746 str++;
1747 p++;
1748 break;
1750 case '*':
1753 * Look for a character matching
1754 * the one after the '*'.
1756 p++;
1757 if(!*p)
1758 return true; /* Automatic match */
1759 while(*str) {
1761 while(*str && (*p != *str))
1762 str++;
1765 * Patch from weidel@multichart.de. In the case of the regexp
1766 * '*XX*' we want to ensure there are at least 2 'X' characters
1767 * in the string after the '*' for a match to be made.
1771 int matchcount=0;
1774 * Eat all the characters that match, but count how many there were.
1777 while(*str && (*p == *str)) {
1778 str++;
1779 matchcount++;
1783 * Now check that if the regexp had n identical characters that
1784 * matchcount had at least that many matches.
1787 while ( *(p+1) && (*(p+1) == *p)) {
1788 p++;
1789 matchcount--;
1792 if ( matchcount <= 0 )
1793 return false;
1796 str--; /* We've eaten the match char after the '*' */
1798 if(unix_do_match(p, str))
1799 return true;
1801 if(!*str)
1802 return false;
1803 else
1804 str++;
1806 return false;
1808 default:
1809 if(*str != *p)
1810 return false;
1811 str++;
1812 p++;
1813 break;
1817 if(!*p && !*str)
1818 return true;
1820 if (!*p && str[0] == '.' && str[1] == 0)
1821 return true;
1823 if (!*str && *p == '?') {
1824 while (*p == '?')
1825 p++;
1826 return(!*p);
1829 if(!*str && (*p == '*' && p[1] == '\0'))
1830 return true;
1832 return false;
1835 /*******************************************************************
1836 Simple case insensitive interface to a UNIX wildcard matcher.
1837 Returns True if match, False if not.
1838 *******************************************************************/
1840 bool unix_wild_match(const char *pattern, const char *string)
1842 TALLOC_CTX *ctx = talloc_stackframe();
1843 char *p2;
1844 char *s2;
1845 char *p;
1846 bool ret = false;
1848 p2 = talloc_strdup(ctx,pattern);
1849 s2 = talloc_strdup(ctx,string);
1850 if (!p2 || !s2) {
1851 TALLOC_FREE(ctx);
1852 return false;
1854 strlower_m(p2);
1855 strlower_m(s2);
1857 /* Remove any *? and ** from the pattern as they are meaningless */
1858 for(p = p2; *p; p++) {
1859 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1860 memmove(&p[1], &p[2], strlen(&p[2])+1);
1864 if (strequal(p2,"*")) {
1865 TALLOC_FREE(ctx);
1866 return true;
1869 ret = unix_do_match(p2, s2);
1870 TALLOC_FREE(ctx);
1871 return ret;
1874 /**********************************************************************
1875 Converts a name to a fully qualified domain name.
1876 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1877 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1878 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1879 ***********************************************************************/
1881 bool name_to_fqdn(fstring fqdn, const char *name)
1883 char *full = NULL;
1884 struct hostent *hp = gethostbyname(name);
1886 if (!hp || !hp->h_name || !*hp->h_name) {
1887 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1888 fstrcpy(fqdn, name);
1889 return false;
1892 /* Find out if the fqdn is returned as an alias
1893 * to cope with /etc/hosts files where the first
1894 * name is not the fqdn but the short name */
1895 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1896 int i;
1897 for (i = 0; hp->h_aliases[i]; i++) {
1898 if (strchr_m(hp->h_aliases[i], '.')) {
1899 full = hp->h_aliases[i];
1900 break;
1904 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1905 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1906 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1907 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1908 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1909 full = hp->h_name;
1911 if (!full) {
1912 full = hp->h_name;
1915 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1916 fstrcpy(fqdn, full);
1917 return true;
1920 /**********************************************************************
1921 Append a DATA_BLOB to a talloc'ed object
1922 ***********************************************************************/
1924 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1926 size_t old_size = 0;
1927 char *result;
1929 if (blob.length == 0) {
1930 return buf;
1933 if (buf != NULL) {
1934 old_size = talloc_get_size(buf);
1937 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1938 if (result == NULL) {
1939 return NULL;
1942 memcpy(result + old_size, blob.data, blob.length);
1943 return result;
1946 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1948 switch (share_access & ~FILE_SHARE_DELETE) {
1949 case FILE_SHARE_NONE:
1950 return DENY_ALL;
1951 case FILE_SHARE_READ:
1952 return DENY_WRITE;
1953 case FILE_SHARE_WRITE:
1954 return DENY_READ;
1955 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1956 return DENY_NONE;
1958 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1959 return DENY_DOS;
1960 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1961 return DENY_FCB;
1964 return (uint32)-1;
1967 pid_t procid_to_pid(const struct server_id *proc)
1969 return proc->pid;
1972 static uint32 my_vnn = NONCLUSTER_VNN;
1974 void set_my_vnn(uint32 vnn)
1976 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1977 my_vnn = vnn;
1980 uint32 get_my_vnn(void)
1982 return my_vnn;
1985 static uint64_t my_unique_id = 0;
1987 void set_my_unique_id(uint64_t unique_id)
1989 my_unique_id = unique_id;
1992 struct server_id pid_to_procid(pid_t pid)
1994 struct server_id result;
1995 result.pid = pid;
1996 result.task_id = 0;
1997 result.unique_id = my_unique_id;
1998 result.vnn = my_vnn;
1999 return result;
2002 struct server_id procid_self(void)
2004 return pid_to_procid(sys_getpid());
2007 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2009 if (p1->pid != p2->pid)
2010 return False;
2011 if (p1->task_id != p2->task_id)
2012 return False;
2013 if (p1->vnn != p2->vnn)
2014 return False;
2015 return True;
2018 bool cluster_id_equal(const struct server_id *id1,
2019 const struct server_id *id2)
2021 return procid_equal(id1, id2);
2024 bool procid_is_me(const struct server_id *pid)
2026 if (pid->pid != sys_getpid())
2027 return False;
2028 if (pid->task_id != 0)
2029 return False;
2030 if (pid->vnn != my_vnn)
2031 return False;
2032 return True;
2035 struct server_id interpret_pid(const char *pid_string)
2037 struct server_id result;
2038 unsigned long long pid;
2039 unsigned int vnn, task_id = 0;
2041 ZERO_STRUCT(result);
2043 /* We accept various forms with 1, 2 or 3 component forms
2044 * because the server_id_str() can print different forms, and
2045 * we want backwards compatibility for scripts that may call
2046 * smbclient. */
2047 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2048 result.vnn = vnn;
2049 result.pid = pid;
2050 result.task_id = task_id;
2051 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2052 result.vnn = vnn;
2053 result.pid = pid;
2054 result.task_id = 0;
2055 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2056 result.vnn = get_my_vnn();
2057 result.pid = pid;
2058 result.task_id = task_id;
2059 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2060 result.vnn = get_my_vnn();
2061 result.pid = pid;
2062 } else {
2063 result.vnn = NONCLUSTER_VNN;
2064 result.pid = (uint64_t)-1;
2066 return result;
2069 char *procid_str_static(const struct server_id *pid)
2071 return server_id_str(talloc_tos(), pid);
2074 bool procid_valid(const struct server_id *pid)
2076 return (pid->pid != (uint64_t)-1);
2079 bool procid_is_local(const struct server_id *pid)
2081 return pid->vnn == my_vnn;
2084 /****************************************************************
2085 Check if an offset into a buffer is safe.
2086 If this returns True it's safe to indirect into the byte at
2087 pointer ptr+off.
2088 ****************************************************************/
2090 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2092 const char *end_base = buf_base + buf_len;
2093 char *end_ptr = ptr + off;
2095 if (!buf_base || !ptr) {
2096 return False;
2099 if (end_base < buf_base || end_ptr < ptr) {
2100 return False; /* wrap. */
2103 if (end_ptr < end_base) {
2104 return True;
2106 return False;
2109 /****************************************************************
2110 Return a safe pointer into a buffer, or NULL.
2111 ****************************************************************/
2113 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2115 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2116 ptr + off : NULL;
2119 /****************************************************************
2120 Return a safe pointer into a string within a buffer, or NULL.
2121 ****************************************************************/
2123 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2125 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2126 return NULL;
2128 /* Check if a valid string exists at this offset. */
2129 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2130 return NULL;
2132 return ptr + off;
2135 /****************************************************************
2136 Return an SVAL at a pointer, or failval if beyond the end.
2137 ****************************************************************/
2139 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2142 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2143 * NOT ptr[2].
2145 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2146 return failval;
2148 return SVAL(ptr,off);
2151 /****************************************************************
2152 Return an IVAL at a pointer, or failval if beyond the end.
2153 ****************************************************************/
2155 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2158 * Note we use off+3 here, not off+4 as IVAL accesses
2159 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2161 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2162 return failval;
2164 return IVAL(ptr,off);
2167 /****************************************************************
2168 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2169 call (they take care of winbind separator and other winbind specific settings).
2170 ****************************************************************/
2172 void split_domain_user(TALLOC_CTX *mem_ctx,
2173 const char *full_name,
2174 char **domain,
2175 char **user)
2177 const char *p = NULL;
2179 p = strchr_m(full_name, '\\');
2181 if (p != NULL) {
2182 *domain = talloc_strndup(mem_ctx, full_name,
2183 PTR_DIFF(p, full_name));
2184 *user = talloc_strdup(mem_ctx, p+1);
2185 } else {
2186 *domain = talloc_strdup(mem_ctx, "");
2187 *user = talloc_strdup(mem_ctx, full_name);
2191 /****************************************************************
2192 strip off leading '\\' from a hostname
2193 ****************************************************************/
2195 const char *strip_hostname(const char *s)
2197 if (!s) {
2198 return NULL;
2201 if (strlen_m(s) < 3) {
2202 return s;
2205 if (s[0] == '\\') s++;
2206 if (s[0] == '\\') s++;
2208 return s;
2211 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2212 struct tevent_context *ev,
2213 NTSTATUS *status)
2215 bool ret = tevent_req_poll(req, ev);
2216 if (!ret) {
2217 *status = map_nt_error_from_unix(errno);
2219 return ret;
2222 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2224 if (!NT_STATUS_IS_OK(err1)) {
2225 *result = err1;
2226 return true;
2228 if (!NT_STATUS_IS_OK(err2)) {
2229 *result = err2;
2230 return true;
2232 return false;
2235 int timeval_to_msec(struct timeval t)
2237 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2240 /*******************************************************************
2241 Check a given DOS pathname is valid for a share.
2242 ********************************************************************/
2244 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2246 char *ptr = NULL;
2248 if (!dos_pathname) {
2249 return NULL;
2252 ptr = talloc_strdup(ctx, dos_pathname);
2253 if (!ptr) {
2254 return NULL;
2256 /* Convert any '\' paths to '/' */
2257 unix_format(ptr);
2258 ptr = unix_clean_name(ctx, ptr);
2259 if (!ptr) {
2260 return NULL;
2263 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2264 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2265 ptr += 2;
2267 /* Only absolute paths allowed. */
2268 if (*ptr != '/')
2269 return NULL;
2271 return ptr;
2274 /*******************************************************************
2275 Return True if the filename is one of the special executable types.
2276 ********************************************************************/
2278 bool is_executable(const char *fname)
2280 if ((fname = strrchr_m(fname,'.'))) {
2281 if (strequal(fname,".com") ||
2282 strequal(fname,".dll") ||
2283 strequal(fname,".exe") ||
2284 strequal(fname,".sym")) {
2285 return True;
2288 return False;
2291 /****************************************************************************
2292 Open a file with a share mode - old openX method - map into NTCreate.
2293 ****************************************************************************/
2295 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2296 int deny_mode, int open_func,
2297 uint32 *paccess_mask,
2298 uint32 *pshare_mode,
2299 uint32 *pcreate_disposition,
2300 uint32 *pcreate_options,
2301 uint32_t *pprivate_flags)
2303 uint32 access_mask;
2304 uint32 share_mode;
2305 uint32 create_disposition;
2306 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2307 uint32_t private_flags = 0;
2309 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2310 "open_func = 0x%x\n",
2311 smb_base_fname, (unsigned int)deny_mode,
2312 (unsigned int)open_func ));
2314 /* Create the NT compatible access_mask. */
2315 switch (GET_OPENX_MODE(deny_mode)) {
2316 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2317 case DOS_OPEN_RDONLY:
2318 access_mask = FILE_GENERIC_READ;
2319 break;
2320 case DOS_OPEN_WRONLY:
2321 access_mask = FILE_GENERIC_WRITE;
2322 break;
2323 case DOS_OPEN_RDWR:
2324 case DOS_OPEN_FCB:
2325 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2326 break;
2327 default:
2328 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2329 (unsigned int)GET_OPENX_MODE(deny_mode)));
2330 return False;
2333 /* Create the NT compatible create_disposition. */
2334 switch (open_func) {
2335 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2336 create_disposition = FILE_CREATE;
2337 break;
2339 case OPENX_FILE_EXISTS_OPEN:
2340 create_disposition = FILE_OPEN;
2341 break;
2343 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2344 create_disposition = FILE_OPEN_IF;
2345 break;
2347 case OPENX_FILE_EXISTS_TRUNCATE:
2348 create_disposition = FILE_OVERWRITE;
2349 break;
2351 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2352 create_disposition = FILE_OVERWRITE_IF;
2353 break;
2355 default:
2356 /* From samba4 - to be confirmed. */
2357 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2358 create_disposition = FILE_CREATE;
2359 break;
2361 DEBUG(10,("map_open_params_to_ntcreate: bad "
2362 "open_func 0x%x\n", (unsigned int)open_func));
2363 return False;
2366 /* Create the NT compatible share modes. */
2367 switch (GET_DENY_MODE(deny_mode)) {
2368 case DENY_ALL:
2369 share_mode = FILE_SHARE_NONE;
2370 break;
2372 case DENY_WRITE:
2373 share_mode = FILE_SHARE_READ;
2374 break;
2376 case DENY_READ:
2377 share_mode = FILE_SHARE_WRITE;
2378 break;
2380 case DENY_NONE:
2381 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2382 break;
2384 case DENY_DOS:
2385 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2386 if (is_executable(smb_base_fname)) {
2387 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2388 } else {
2389 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2390 share_mode = FILE_SHARE_READ;
2391 } else {
2392 share_mode = FILE_SHARE_NONE;
2395 break;
2397 case DENY_FCB:
2398 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2399 share_mode = FILE_SHARE_NONE;
2400 break;
2402 default:
2403 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2404 (unsigned int)GET_DENY_MODE(deny_mode) ));
2405 return False;
2408 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2409 "share_mode = 0x%x, create_disposition = 0x%x, "
2410 "create_options = 0x%x private_flags = 0x%x\n",
2411 smb_base_fname,
2412 (unsigned int)access_mask,
2413 (unsigned int)share_mode,
2414 (unsigned int)create_disposition,
2415 (unsigned int)create_options,
2416 (unsigned int)private_flags));
2418 if (paccess_mask) {
2419 *paccess_mask = access_mask;
2421 if (pshare_mode) {
2422 *pshare_mode = share_mode;
2424 if (pcreate_disposition) {
2425 *pcreate_disposition = create_disposition;
2427 if (pcreate_options) {
2428 *pcreate_options = create_options;
2430 if (pprivate_flags) {
2431 *pprivate_flags = private_flags;
2434 return True;
2439 void init_modules(void)
2441 /* FIXME: This can cause undefined symbol errors :
2442 * smb_register_vfs() isn't available in nmbd, for example */
2443 if(lp_preload_modules())
2444 smb_load_modules(lp_preload_modules());