build: Remove SMB_STRUCT_DIRENT define
[Samba.git] / source3 / lib / util.c
blobb727f7b3d880c30a5f97d76976ecce177c972ec7
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "util_tdb.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
30 #include "messages.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
36 #endif
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
52 #if defined(GROUP)
53 #undef GROUP
54 #endif
56 #if defined(GROUP_OBJ)
57 #undef GROUP_OBJ
58 #endif
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
69 enum protocol_types get_Protocol(void)
71 return Protocol;
74 void set_Protocol(enum protocol_types p)
76 Protocol = p;
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
83 gfree_names();
84 gfree_loadparm();
85 gfree_charcnv();
86 gfree_interfaces();
87 gfree_debugsyms();
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95 bool fake_dir_create_times)
97 SMB_STRUCT_STAT st;
98 if (!sbuf)
99 sbuf = &st;
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
102 return(False);
104 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname)
113 SMB_STRUCT_STAT st;
114 if (sys_stat(fname, &st, false) != 0)
115 return(False);
117 return S_ISSOCK(st.st_ex_mode);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
126 return sbuf->st_ex_size;
129 /*******************************************************************
130 Show a smb message structure.
131 ********************************************************************/
133 void show_msg(const char *buf)
135 int i;
136 int bcc=0;
138 if (!DEBUGLVL(5))
139 return;
141 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
142 smb_len(buf),
143 (int)CVAL(buf,smb_com),
144 (int)CVAL(buf,smb_rcls),
145 (int)CVAL(buf,smb_reh),
146 (int)SVAL(buf,smb_err),
147 (int)CVAL(buf,smb_flg),
148 (int)SVAL(buf,smb_flg2)));
149 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
150 (int)SVAL(buf,smb_tid),
151 (int)SVAL(buf,smb_pid),
152 (int)SVAL(buf,smb_uid),
153 (int)SVAL(buf,smb_mid)));
154 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
156 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
157 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
158 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
160 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
162 DEBUGADD(5,("smb_bcc=%d\n",bcc));
164 if (DEBUGLEVEL < 10)
165 return;
167 if (DEBUGLEVEL < 50)
168 bcc = MIN(bcc, 512);
170 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
173 /*******************************************************************
174 Setup only the byte count for a smb message.
175 ********************************************************************/
177 int set_message_bcc(char *buf,int num_bytes)
179 int num_words = CVAL(buf,smb_wct);
180 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
181 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
182 return (smb_size + num_words*2 + num_bytes);
185 /*******************************************************************
186 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
187 Return the bytes added
188 ********************************************************************/
190 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
192 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
193 uint8 *tmp;
195 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
196 DEBUG(0, ("talloc failed\n"));
197 return -1;
199 *outbuf = tmp;
201 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
202 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
203 return blob.length;
206 /*******************************************************************
207 Reduce a file name, removing .. elements.
208 ********************************************************************/
210 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
212 char *p = NULL;
213 char *str = NULL;
215 DEBUG(3,("dos_clean_name [%s]\n",s));
217 /* remove any double slashes */
218 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
219 if (!str) {
220 return NULL;
223 /* Remove leading .\\ characters */
224 if(strncmp(str, ".\\", 2) == 0) {
225 trim_string(str, ".\\", NULL);
226 if(*str == 0) {
227 str = talloc_strdup(ctx, ".\\");
228 if (!str) {
229 return NULL;
234 while ((p = strstr_m(str,"\\..\\")) != NULL) {
235 char *s1;
237 *p = 0;
238 s1 = p+3;
240 if ((p=strrchr_m(str,'\\')) != NULL) {
241 *p = 0;
242 } else {
243 *str = 0;
245 str = talloc_asprintf(ctx,
246 "%s%s",
247 str,
248 s1);
249 if (!str) {
250 return NULL;
254 trim_string(str,NULL,"\\..");
255 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
258 /*******************************************************************
259 Reduce a file name, removing .. elements.
260 ********************************************************************/
262 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
264 char *p = NULL;
265 char *str = NULL;
267 DEBUG(3,("unix_clean_name [%s]\n",s));
269 /* remove any double slashes */
270 str = talloc_all_string_sub(ctx, s, "//","/");
271 if (!str) {
272 return NULL;
275 /* Remove leading ./ characters */
276 if(strncmp(str, "./", 2) == 0) {
277 trim_string(str, "./", NULL);
278 if(*str == 0) {
279 str = talloc_strdup(ctx, "./");
280 if (!str) {
281 return NULL;
286 while ((p = strstr_m(str,"/../")) != NULL) {
287 char *s1;
289 *p = 0;
290 s1 = p+3;
292 if ((p=strrchr_m(str,'/')) != NULL) {
293 *p = 0;
294 } else {
295 *str = 0;
297 str = talloc_asprintf(ctx,
298 "%s%s",
299 str,
300 s1);
301 if (!str) {
302 return NULL;
306 trim_string(str,NULL,"/..");
307 return talloc_all_string_sub(ctx, str, "/./", "/");
310 char *clean_name(TALLOC_CTX *ctx, const char *s)
312 char *str = dos_clean_name(ctx, s);
313 if (!str) {
314 return NULL;
316 return unix_clean_name(ctx, str);
319 /*******************************************************************
320 Write data into an fd at a given offset. Ignore seek errors.
321 ********************************************************************/
323 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
325 size_t total=0;
326 ssize_t ret;
328 if (pos == (SMB_OFF_T)-1) {
329 return write_data(fd, buffer, N);
331 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
332 while (total < N) {
333 ret = sys_pwrite(fd,buffer + total,N - total, pos);
334 if (ret == -1 && errno == ESPIPE) {
335 return write_data(fd, buffer + total,N - total);
337 if (ret == -1) {
338 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
339 return -1;
341 if (ret == 0) {
342 return total;
344 total += ret;
345 pos += ret;
347 return (ssize_t)total;
348 #else
349 /* Use lseek and write_data. */
350 if (lseek(fd, pos, SEEK_SET) == -1) {
351 if (errno != ESPIPE) {
352 return -1;
355 return write_data(fd, buffer, N);
356 #endif
359 static int reinit_after_fork_pipe[2] = { -1, -1 };
361 NTSTATUS init_before_fork(void)
363 int ret;
365 ret = pipe(reinit_after_fork_pipe);
366 if (ret == -1) {
367 NTSTATUS status;
369 status = map_nt_error_from_unix_common(errno);
371 DEBUG(0, ("Error creating child_pipe: %s\n",
372 nt_errstr(status)));
374 return status;
377 return NT_STATUS_OK;
381 * Detect died parent by detecting EOF on the pipe
383 static void reinit_after_fork_pipe_handler(struct tevent_context *ev,
384 struct tevent_fd *fde,
385 uint16_t flags,
386 void *private_data)
388 char c;
390 if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) {
392 * we have reached EOF on stdin, which means the
393 * parent has exited. Shutdown the server
395 (void)kill(getpid(), SIGTERM);
400 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
401 struct event_context *ev_ctx,
402 bool parent_longlived)
404 NTSTATUS status = NT_STATUS_OK;
406 if (reinit_after_fork_pipe[1] != -1) {
407 close(reinit_after_fork_pipe[1]);
408 reinit_after_fork_pipe[1] = -1;
411 /* Reset the state of the random
412 * number generation system, so
413 * children do not get the same random
414 * numbers as each other */
415 set_need_random_reseed();
417 /* tdb needs special fork handling */
418 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
419 DEBUG(0,("tdb_reopen_all failed.\n"));
420 status = NT_STATUS_OPEN_FAILED;
421 goto done;
424 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
425 smb_panic(__location__ ": Failed to re-initialise event context");
428 if (reinit_after_fork_pipe[0] != -1) {
429 struct tevent_fd *fde;
431 fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */,
432 reinit_after_fork_pipe[0], TEVENT_FD_READ,
433 reinit_after_fork_pipe_handler, NULL);
434 if (fde == NULL) {
435 smb_panic(__location__ ": Failed to add reinit_after_fork pipe event");
439 if (msg_ctx) {
441 * For clustering, we need to re-init our ctdbd connection after the
442 * fork
444 status = messaging_reinit(msg_ctx);
445 if (!NT_STATUS_IS_OK(status)) {
446 DEBUG(0,("messaging_reinit() failed: %s\n",
447 nt_errstr(status)));
450 done:
451 return status;
454 /****************************************************************************
455 (Hopefully) efficient array append.
456 ****************************************************************************/
458 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
459 void *element, void *_array, uint32 *num_elements,
460 ssize_t *array_size)
462 void **array = (void **)_array;
464 if (*array_size < 0) {
465 return;
468 if (*array == NULL) {
469 if (*array_size == 0) {
470 *array_size = 128;
473 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
474 goto error;
477 *array = TALLOC(mem_ctx, element_size * (*array_size));
478 if (*array == NULL) {
479 goto error;
483 if (*num_elements == *array_size) {
484 *array_size *= 2;
486 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
487 goto error;
490 *array = TALLOC_REALLOC(mem_ctx, *array,
491 element_size * (*array_size));
493 if (*array == NULL) {
494 goto error;
498 memcpy((char *)(*array) + element_size*(*num_elements),
499 element, element_size);
500 *num_elements += 1;
502 return;
504 error:
505 *num_elements = 0;
506 *array_size = -1;
509 /****************************************************************************
510 Get my own domain name, or "" if we have none.
511 ****************************************************************************/
513 char *get_mydnsdomname(TALLOC_CTX *ctx)
515 const char *domname;
516 char *p;
518 domname = get_mydnsfullname();
519 if (!domname) {
520 return NULL;
523 p = strchr_m(domname, '.');
524 if (p) {
525 p++;
526 return talloc_strdup(ctx, p);
527 } else {
528 return talloc_strdup(ctx, "");
532 /****************************************************************************
533 Interpret a protocol description string, with a default.
534 ****************************************************************************/
536 int interpret_protocol(const char *str,int def)
538 if (strequal(str,"NT1"))
539 return(PROTOCOL_NT1);
540 if (strequal(str,"LANMAN2"))
541 return(PROTOCOL_LANMAN2);
542 if (strequal(str,"LANMAN1"))
543 return(PROTOCOL_LANMAN1);
544 if (strequal(str,"CORE"))
545 return(PROTOCOL_CORE);
546 if (strequal(str,"COREPLUS"))
547 return(PROTOCOL_COREPLUS);
548 if (strequal(str,"CORE+"))
549 return(PROTOCOL_COREPLUS);
551 DEBUG(0,("Unrecognised protocol level %s\n",str));
553 return(def);
557 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
558 /******************************************************************
559 Remove any mount options such as -rsize=2048,wsize=2048 etc.
560 Based on a fix from <Thomas.Hepper@icem.de>.
561 Returns a malloc'ed string.
562 *******************************************************************/
564 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
566 if (*str == '-') {
567 const char *p = str;
568 while(*p && !isspace(*p))
569 p++;
570 while(*p && isspace(*p))
571 p++;
572 if(*p) {
573 return talloc_strdup(ctx, p);
576 return NULL;
579 /*******************************************************************
580 Patch from jkf@soton.ac.uk
581 Split Luke's automount_server into YP lookup and string splitter
582 so can easily implement automount_path().
583 Returns a malloc'ed string.
584 *******************************************************************/
586 #ifdef WITH_NISPLUS_HOME
587 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
589 char *value = NULL;
591 char *nis_map = (char *)lp_nis_home_map_name();
593 char buffer[NIS_MAXATTRVAL + 1];
594 nis_result *result;
595 nis_object *object;
596 entry_obj *entry;
598 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
599 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
601 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
602 if (result->status != NIS_SUCCESS) {
603 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
604 } else {
605 object = result->objects.objects_val;
606 if (object->zo_data.zo_type == ENTRY_OBJ) {
607 entry = &object->zo_data.objdata_u.en_data;
608 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
609 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
611 value = talloc_strdup(ctx,
612 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
613 if (!value) {
614 nis_freeresult(result);
615 return NULL;
617 value = talloc_string_sub(ctx,
618 value,
619 "&",
620 user_name);
624 nis_freeresult(result);
626 if (value) {
627 value = strip_mount_options(ctx, value);
628 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
629 user_name, value));
631 return value;
633 #else /* WITH_NISPLUS_HOME */
635 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
637 char *value = NULL;
639 int nis_error; /* returned by yp all functions */
640 char *nis_result; /* yp_match inits this */
641 int nis_result_len; /* and set this */
642 char *nis_domain; /* yp_get_default_domain inits this */
643 char *nis_map = (char *)lp_nis_home_map_name();
645 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
646 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
647 return NULL;
650 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
652 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
653 strlen(user_name), &nis_result,
654 &nis_result_len)) == 0) {
655 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
656 nis_result[nis_result_len] = '\0';
658 value = talloc_strdup(ctx, nis_result);
659 if (!value) {
660 return NULL;
662 value = strip_mount_options(ctx, value);
663 } else if(nis_error == YPERR_KEY) {
664 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
665 user_name, nis_map));
666 DEBUG(3, ("using defaults for server and home directory\n"));
667 } else {
668 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
669 yperr_string(nis_error), user_name, nis_map));
672 if (value) {
673 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
675 return value;
677 #endif /* WITH_NISPLUS_HOME */
678 #endif
680 /****************************************************************************
681 Check if a process exists. Does this work on all unixes?
682 ****************************************************************************/
684 bool process_exists(const struct server_id pid)
686 if (procid_is_me(&pid)) {
687 return True;
690 if (procid_is_local(&pid)) {
691 return (kill(pid.pid,0) == 0 || errno != ESRCH);
694 #ifdef CLUSTER_SUPPORT
695 return ctdbd_process_exists(messaging_ctdbd_connection(),
696 pid.vnn, pid.pid);
697 #else
698 return False;
699 #endif
702 bool processes_exist(const struct server_id *pids, int num_pids,
703 bool *results)
705 struct server_id *remote_pids = NULL;
706 int *remote_idx = NULL;
707 bool *remote_results = NULL;
708 int i, num_remote_pids;
709 bool result = false;
711 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
712 if (remote_pids == NULL) {
713 goto fail;
715 remote_idx = talloc_array(talloc_tos(), int, num_pids);
716 if (remote_idx == NULL) {
717 goto fail;
719 remote_results = talloc_array(talloc_tos(), bool, num_pids);
720 if (remote_results == NULL) {
721 goto fail;
724 num_remote_pids = 0;
726 for (i=0; i<num_pids; i++) {
727 if (procid_is_me(&pids[i])) {
728 results[i] = true;
729 continue;
731 if (procid_is_local(&pids[i])) {
732 results[i] = ((kill(pids[i].pid,0) == 0) ||
733 (errno != ESRCH));
734 continue;
737 remote_pids[num_remote_pids] = pids[i];
738 remote_idx[num_remote_pids] = i;
739 num_remote_pids += 1;
742 if (num_remote_pids != 0) {
743 #ifdef CLUSTER_SUPPORT
744 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
745 remote_pids, num_remote_pids,
746 remote_results)) {
747 goto fail;
749 #else
750 for (i=0; i<num_remote_pids; i++) {
751 remote_results[i] = false;
753 #endif
755 for (i=0; i<num_remote_pids; i++) {
756 results[remote_idx[i]] = remote_results[i];
760 result = true;
761 fail:
762 TALLOC_FREE(remote_results);
763 TALLOC_FREE(remote_idx);
764 TALLOC_FREE(remote_pids);
765 return result;
768 /*******************************************************************
769 Convert a uid into a user name.
770 ********************************************************************/
772 const char *uidtoname(uid_t uid)
774 TALLOC_CTX *ctx = talloc_tos();
775 char *name = NULL;
776 struct passwd *pass = NULL;
778 pass = getpwuid_alloc(ctx,uid);
779 if (pass) {
780 name = talloc_strdup(ctx,pass->pw_name);
781 TALLOC_FREE(pass);
782 } else {
783 name = talloc_asprintf(ctx,
784 "%ld",
785 (long int)uid);
787 return name;
790 /*******************************************************************
791 Convert a gid into a group name.
792 ********************************************************************/
794 char *gidtoname(gid_t gid)
796 struct group *grp;
798 grp = getgrgid(gid);
799 if (grp) {
800 return talloc_strdup(talloc_tos(), grp->gr_name);
802 else {
803 return talloc_asprintf(talloc_tos(),
804 "%d",
805 (int)gid);
809 /*******************************************************************
810 Convert a user name into a uid.
811 ********************************************************************/
813 uid_t nametouid(const char *name)
815 struct passwd *pass;
816 char *p;
817 uid_t u;
819 pass = Get_Pwnam_alloc(talloc_tos(), name);
820 if (pass) {
821 u = pass->pw_uid;
822 TALLOC_FREE(pass);
823 return u;
826 u = (uid_t)strtol(name, &p, 0);
827 if ((p != name) && (*p == '\0'))
828 return u;
830 return (uid_t)-1;
833 /*******************************************************************
834 Convert a name to a gid_t if possible. Return -1 if not a group.
835 ********************************************************************/
837 gid_t nametogid(const char *name)
839 struct group *grp;
840 char *p;
841 gid_t g;
843 g = (gid_t)strtol(name, &p, 0);
844 if ((p != name) && (*p == '\0'))
845 return g;
847 grp = getgrnam(name);
848 if (grp)
849 return(grp->gr_gid);
850 return (gid_t)-1;
853 /*******************************************************************
854 Something really nasty happened - panic !
855 ********************************************************************/
857 void smb_panic_s3(const char *why)
859 char *cmd;
860 int result;
862 DEBUG(0,("PANIC (pid %llu): %s\n",
863 (unsigned long long)getpid(), why));
864 log_stack_trace();
866 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
868 * Make sure all children can attach a debugger.
870 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
871 #endif
873 cmd = lp_panic_action();
874 if (cmd && *cmd) {
875 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
876 result = system(cmd);
878 if (result == -1)
879 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
880 strerror(errno)));
881 else
882 DEBUG(0, ("smb_panic(): action returned status %d\n",
883 WEXITSTATUS(result)));
886 dump_core();
889 /*******************************************************************
890 Print a backtrace of the stack to the debug log. This function
891 DELIBERATELY LEAKS MEMORY. The expectation is that you should
892 exit shortly after calling it.
893 ********************************************************************/
895 #ifdef HAVE_LIBUNWIND_H
896 #include <libunwind.h>
897 #endif
899 #ifdef HAVE_EXECINFO_H
900 #include <execinfo.h>
901 #endif
903 #ifdef HAVE_LIBEXC_H
904 #include <libexc.h>
905 #endif
907 void log_stack_trace(void)
909 #ifdef HAVE_LIBUNWIND
910 /* Try to use libunwind before any other technique since on ia64
911 * libunwind correctly walks the stack in more circumstances than
912 * backtrace.
914 unw_cursor_t cursor;
915 unw_context_t uc;
916 unsigned i = 0;
918 char procname[256];
919 unw_word_t ip, sp, off;
921 procname[sizeof(procname) - 1] = '\0';
923 if (unw_getcontext(&uc) != 0) {
924 goto libunwind_failed;
927 if (unw_init_local(&cursor, &uc) != 0) {
928 goto libunwind_failed;
931 DEBUG(0, ("BACKTRACE:\n"));
933 do {
934 ip = sp = 0;
935 unw_get_reg(&cursor, UNW_REG_IP, &ip);
936 unw_get_reg(&cursor, UNW_REG_SP, &sp);
938 switch (unw_get_proc_name(&cursor,
939 procname, sizeof(procname) - 1, &off) ) {
940 case 0:
941 /* Name found. */
942 case -UNW_ENOMEM:
943 /* Name truncated. */
944 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
945 i, procname, (long long)off,
946 (long long)ip, (long long) sp));
947 break;
948 default:
949 /* case -UNW_ENOINFO: */
950 /* case -UNW_EUNSPEC: */
951 /* No symbol name found. */
952 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
953 i, "<unknown symbol>",
954 (long long)ip, (long long) sp));
956 ++i;
957 } while (unw_step(&cursor) > 0);
959 return;
961 libunwind_failed:
962 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
964 #elif HAVE_BACKTRACE_SYMBOLS
965 void *backtrace_stack[BACKTRACE_STACK_SIZE];
966 size_t backtrace_size;
967 char **backtrace_strings;
969 /* get the backtrace (stack frames) */
970 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
971 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
973 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
974 (unsigned long)backtrace_size));
976 if (backtrace_strings) {
977 int i;
979 for (i = 0; i < backtrace_size; i++)
980 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
982 /* Leak the backtrace_strings, rather than risk what free() might do */
985 #elif HAVE_LIBEXC
987 /* The IRIX libexc library provides an API for unwinding the stack. See
988 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
989 * since we are about to abort anyway, it hardly matters.
992 #define NAMESIZE 32 /* Arbitrary */
994 __uint64_t addrs[BACKTRACE_STACK_SIZE];
995 char * names[BACKTRACE_STACK_SIZE];
996 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
998 int i;
999 int levels;
1001 ZERO_ARRAY(addrs);
1002 ZERO_ARRAY(names);
1003 ZERO_ARRAY(namebuf);
1005 /* We need to be root so we can open our /proc entry to walk
1006 * our stack. It also helps when we want to dump core.
1008 become_root();
1010 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1011 names[i] = namebuf + (i * NAMESIZE);
1014 levels = trace_back_stack(0, addrs, names,
1015 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1017 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1018 for (i = 0; i < levels; i++) {
1019 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1021 #undef NAMESIZE
1023 #else
1024 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1025 #endif
1028 /*******************************************************************
1029 A readdir wrapper which just returns the file name.
1030 ********************************************************************/
1032 const char *readdirname(SMB_STRUCT_DIR *p)
1034 struct dirent *ptr;
1035 char *dname;
1037 if (!p)
1038 return(NULL);
1040 ptr = (struct dirent *)readdir(p);
1041 if (!ptr)
1042 return(NULL);
1044 dname = ptr->d_name;
1046 #ifdef NEXT2
1047 if (telldir(p) < 0)
1048 return(NULL);
1049 #endif
1051 #ifdef HAVE_BROKEN_READDIR_NAME
1052 /* using /usr/ucb/cc is BAD */
1053 dname = dname - 2;
1054 #endif
1056 return talloc_strdup(talloc_tos(), dname);
1059 /*******************************************************************
1060 Utility function used to decide if the last component
1061 of a path matches a (possibly wildcarded) entry in a namelist.
1062 ********************************************************************/
1064 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1066 const char *last_component;
1068 /* if we have no list it's obviously not in the path */
1069 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1070 return False;
1073 DEBUG(8, ("is_in_path: %s\n", name));
1075 /* Get the last component of the unix name. */
1076 last_component = strrchr_m(name, '/');
1077 if (!last_component) {
1078 last_component = name;
1079 } else {
1080 last_component++; /* Go past '/' */
1083 for(; namelist->name != NULL; namelist++) {
1084 if(namelist->is_wild) {
1085 if (mask_match(last_component, namelist->name, case_sensitive)) {
1086 DEBUG(8,("is_in_path: mask match succeeded\n"));
1087 return True;
1089 } else {
1090 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1091 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1092 DEBUG(8,("is_in_path: match succeeded\n"));
1093 return True;
1097 DEBUG(8,("is_in_path: match not found\n"));
1098 return False;
1101 /*******************************************************************
1102 Strip a '/' separated list into an array of
1103 name_compare_enties structures suitable for
1104 passing to is_in_path(). We do this for
1105 speed so we can pre-parse all the names in the list
1106 and don't do it for each call to is_in_path().
1107 We also check if the entry contains a wildcard to
1108 remove a potentially expensive call to mask_match
1109 if possible.
1110 ********************************************************************/
1112 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1114 char *name_end;
1115 char *namelist;
1116 char *nameptr;
1117 int num_entries = 0;
1118 int i;
1120 (*ppname_array) = NULL;
1122 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1123 return;
1125 namelist = talloc_strdup(talloc_tos(), namelist_in);
1126 if (namelist == NULL) {
1127 DEBUG(0,("set_namearray: talloc fail\n"));
1128 return;
1130 nameptr = namelist;
1132 /* We need to make two passes over the string. The
1133 first to count the number of elements, the second
1134 to split it.
1137 while(*nameptr) {
1138 if ( *nameptr == '/' ) {
1139 /* cope with multiple (useless) /s) */
1140 nameptr++;
1141 continue;
1143 /* anything left? */
1144 if ( *nameptr == '\0' )
1145 break;
1147 /* find the next '/' or consume remaining */
1148 name_end = strchr_m(nameptr, '/');
1149 if (name_end == NULL)
1150 name_end = (char *)nameptr + strlen(nameptr);
1152 /* next segment please */
1153 nameptr = name_end + 1;
1154 num_entries++;
1157 if(num_entries == 0) {
1158 talloc_free(namelist);
1159 return;
1162 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1163 DEBUG(0,("set_namearray: malloc fail\n"));
1164 talloc_free(namelist);
1165 return;
1168 /* Now copy out the names */
1169 nameptr = namelist;
1170 i = 0;
1171 while(*nameptr) {
1172 if ( *nameptr == '/' ) {
1173 /* cope with multiple (useless) /s) */
1174 nameptr++;
1175 continue;
1177 /* anything left? */
1178 if ( *nameptr == '\0' )
1179 break;
1181 /* find the next '/' or consume remaining */
1182 name_end = strchr_m(nameptr, '/');
1183 if (name_end)
1184 *name_end = '\0';
1185 else
1186 name_end = nameptr + strlen(nameptr);
1188 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1189 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1190 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1191 talloc_free(namelist);
1192 return;
1195 /* next segment please */
1196 nameptr = name_end + 1;
1197 i++;
1200 (*ppname_array)[i].name = NULL;
1202 talloc_free(namelist);
1203 return;
1206 #undef DBGC_CLASS
1207 #define DBGC_CLASS DBGC_LOCKING
1209 /****************************************************************************
1210 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1211 is dealt with in posix.c
1212 Returns True if we have information regarding this lock region (and returns
1213 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1214 ****************************************************************************/
1216 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1218 SMB_STRUCT_FLOCK lock;
1219 int ret;
1221 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1222 fd,(double)*poffset,(double)*pcount,*ptype));
1224 lock.l_type = *ptype;
1225 lock.l_whence = SEEK_SET;
1226 lock.l_start = *poffset;
1227 lock.l_len = *pcount;
1228 lock.l_pid = 0;
1230 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1232 if (ret == -1) {
1233 int sav = errno;
1234 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1235 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1236 errno = sav;
1237 return False;
1240 *ptype = lock.l_type;
1241 *poffset = lock.l_start;
1242 *pcount = lock.l_len;
1243 *ppid = lock.l_pid;
1245 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1246 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1247 return True;
1250 #undef DBGC_CLASS
1251 #define DBGC_CLASS DBGC_ALL
1253 /*******************************************************************
1254 Is the name specified one of my netbios names.
1255 Returns true if it is equal, false otherwise.
1256 ********************************************************************/
1258 bool is_myname(const char *s)
1260 int n;
1261 bool ret = False;
1263 for (n=0; my_netbios_names(n); n++) {
1264 if (strequal(my_netbios_names(n), s)) {
1265 ret=True;
1266 break;
1269 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1270 return(ret);
1273 /*******************************************************************
1274 we distinguish between 2K and XP by the "Native Lan Manager" string
1275 WinXP => "Windows 2002 5.1"
1276 WinXP 64bit => "Windows XP 5.2"
1277 Win2k => "Windows 2000 5.0"
1278 NT4 => "Windows NT 4.0"
1279 Win9x => "Windows 4.0"
1280 Windows 2003 doesn't set the native lan manager string but
1281 they do set the domain to "Windows 2003 5.2" (probably a bug).
1282 ********************************************************************/
1284 void ra_lanman_string( const char *native_lanman )
1286 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1287 set_remote_arch( RA_WINXP );
1288 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1289 set_remote_arch( RA_WINXP64 );
1290 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1291 set_remote_arch( RA_WIN2K3 );
1294 static const char *remote_arch_str;
1296 const char *get_remote_arch_str(void)
1298 if (!remote_arch_str) {
1299 return "UNKNOWN";
1301 return remote_arch_str;
1304 /*******************************************************************
1305 Set the horrid remote_arch string based on an enum.
1306 ********************************************************************/
1308 void set_remote_arch(enum remote_arch_types type)
1310 ra_type = type;
1311 switch( type ) {
1312 case RA_WFWG:
1313 remote_arch_str = "WfWg";
1314 break;
1315 case RA_OS2:
1316 remote_arch_str = "OS2";
1317 break;
1318 case RA_WIN95:
1319 remote_arch_str = "Win95";
1320 break;
1321 case RA_WINNT:
1322 remote_arch_str = "WinNT";
1323 break;
1324 case RA_WIN2K:
1325 remote_arch_str = "Win2K";
1326 break;
1327 case RA_WINXP:
1328 remote_arch_str = "WinXP";
1329 break;
1330 case RA_WINXP64:
1331 remote_arch_str = "WinXP64";
1332 break;
1333 case RA_WIN2K3:
1334 remote_arch_str = "Win2K3";
1335 break;
1336 case RA_VISTA:
1337 remote_arch_str = "Vista";
1338 break;
1339 case RA_SAMBA:
1340 remote_arch_str = "Samba";
1341 break;
1342 case RA_CIFSFS:
1343 remote_arch_str = "CIFSFS";
1344 break;
1345 case RA_OSX:
1346 remote_arch_str = "OSX";
1347 break;
1348 default:
1349 ra_type = RA_UNKNOWN;
1350 remote_arch_str = "UNKNOWN";
1351 break;
1354 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1355 remote_arch_str));
1358 /*******************************************************************
1359 Get the remote_arch type.
1360 ********************************************************************/
1362 enum remote_arch_types get_remote_arch(void)
1364 return ra_type;
1367 const char *tab_depth(int level, int depth)
1369 if( CHECK_DEBUGLVL(level) ) {
1370 dbgtext("%*s", depth*4, "");
1372 return "";
1375 /*****************************************************************************
1376 Provide a checksum on a string
1378 Input: s - the null-terminated character string for which the checksum
1379 will be calculated.
1381 Output: The checksum value calculated for s.
1382 *****************************************************************************/
1384 int str_checksum(const char *s)
1386 if (s == NULL)
1387 return 0;
1388 return hash(s, strlen(s), 0);
1391 /*****************************************************************
1392 Zero a memory area then free it. Used to catch bugs faster.
1393 *****************************************************************/
1395 void zero_free(void *p, size_t size)
1397 memset(p, 0, size);
1398 SAFE_FREE(p);
1401 /*****************************************************************
1402 Set our open file limit to a requested max and return the limit.
1403 *****************************************************************/
1405 int set_maxfiles(int requested_max)
1407 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1408 struct rlimit rlp;
1409 int saved_current_limit;
1411 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1412 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1413 strerror(errno) ));
1414 /* just guess... */
1415 return requested_max;
1419 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1420 * account for the extra fd we need
1421 * as well as the log files and standard
1422 * handles etc. Save the limit we want to set in case
1423 * we are running on an OS that doesn't support this limit (AIX)
1424 * which always returns RLIM_INFINITY for rlp.rlim_max.
1427 /* Try raising the hard (max) limit to the requested amount. */
1429 #if defined(RLIM_INFINITY)
1430 if (rlp.rlim_max != RLIM_INFINITY) {
1431 int orig_max = rlp.rlim_max;
1433 if ( rlp.rlim_max < requested_max )
1434 rlp.rlim_max = requested_max;
1436 /* This failing is not an error - many systems (Linux) don't
1437 support our default request of 10,000 open files. JRA. */
1439 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1440 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1441 (int)rlp.rlim_max, strerror(errno) ));
1443 /* Set failed - restore original value from get. */
1444 rlp.rlim_max = orig_max;
1447 #endif
1449 /* Now try setting the soft (current) limit. */
1451 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1453 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1454 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1455 (int)rlp.rlim_cur, strerror(errno) ));
1456 /* just guess... */
1457 return saved_current_limit;
1460 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1461 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1462 strerror(errno) ));
1463 /* just guess... */
1464 return saved_current_limit;
1467 #if defined(RLIM_INFINITY)
1468 if(rlp.rlim_cur == RLIM_INFINITY)
1469 return saved_current_limit;
1470 #endif
1472 if((int)rlp.rlim_cur > saved_current_limit)
1473 return saved_current_limit;
1475 return rlp.rlim_cur;
1476 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1478 * No way to know - just guess...
1480 return requested_max;
1481 #endif
1484 /*****************************************************************
1485 malloc that aborts with smb_panic on fail or zero size.
1486 *****************************************************************/
1488 void *smb_xmalloc_array(size_t size, unsigned int count)
1490 void *p;
1491 if (size == 0) {
1492 smb_panic("smb_xmalloc_array: called with zero size");
1494 if (count >= MAX_ALLOC_SIZE/size) {
1495 smb_panic("smb_xmalloc_array: alloc size too large");
1497 if ((p = SMB_MALLOC(size*count)) == NULL) {
1498 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1499 (unsigned long)size, (unsigned long)count));
1500 smb_panic("smb_xmalloc_array: malloc failed");
1502 return p;
1506 vasprintf that aborts on malloc fail
1509 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1511 int n;
1512 va_list ap2;
1514 va_copy(ap2, ap);
1516 n = vasprintf(ptr, format, ap2);
1517 va_end(ap2);
1518 if (n == -1 || ! *ptr) {
1519 smb_panic("smb_xvasprintf: out of memory");
1521 return n;
1524 /*****************************************************************
1525 Get local hostname and cache result.
1526 *****************************************************************/
1528 char *myhostname(void)
1530 static char *ret;
1531 if (ret == NULL) {
1532 ret = get_myname(NULL);
1534 return ret;
1537 /*****************************************************************
1538 Get local hostname and cache result.
1539 *****************************************************************/
1541 char *myhostname_upper(void)
1543 char *name;
1544 static char *ret;
1545 if (ret == NULL) {
1546 name = get_myname(talloc_tos());
1547 ret = strupper_talloc(NULL, name);
1548 talloc_free(name);
1550 return ret;
1554 * @brief Returns an absolute path to a file concatenating the provided
1555 * @a rootpath and @a basename
1557 * @param name Filename, relative to @a rootpath
1559 * @retval Pointer to a string containing the full path.
1562 static char *xx_path(const char *name, const char *rootpath)
1564 char *fname = NULL;
1566 fname = talloc_strdup(talloc_tos(), rootpath);
1567 if (!fname) {
1568 return NULL;
1570 trim_string(fname,"","/");
1572 if (!directory_exist(fname)) {
1573 if (!mkdir(fname,0755))
1574 DEBUG(1, ("Unable to create directory %s for file %s. "
1575 "Error was %s\n", fname, name, strerror(errno)));
1578 return talloc_asprintf(talloc_tos(),
1579 "%s/%s",
1580 fname,
1581 name);
1585 * @brief Returns an absolute path to a file in the Samba lock directory.
1587 * @param name File to find, relative to LOCKDIR.
1589 * @retval Pointer to a talloc'ed string containing the full path.
1592 char *lock_path(const char *name)
1594 return xx_path(name, lp_lockdir());
1598 * @brief Returns an absolute path to a file in the Samba state directory.
1600 * @param name File to find, relative to STATEDIR.
1602 * @retval Pointer to a talloc'ed string containing the full path.
1605 char *state_path(const char *name)
1607 return xx_path(name, lp_statedir());
1611 * @brief Returns an absolute path to a file in the Samba cache directory.
1613 * @param name File to find, relative to CACHEDIR.
1615 * @retval Pointer to a talloc'ed string containing the full path.
1618 char *cache_path(const char *name)
1620 return xx_path(name, lp_cachedir());
1623 /*******************************************************************
1624 Given a filename - get its directory name
1625 ********************************************************************/
1627 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1628 const char **name)
1630 char *p;
1631 ptrdiff_t len;
1633 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1635 if (p == NULL) {
1636 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1637 return False;
1639 if (name) {
1640 *name = dir;
1642 return True;
1645 len = p-dir;
1647 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1648 return False;
1650 (*parent)[len] = '\0';
1652 if (name) {
1653 *name = p+1;
1655 return True;
1658 /*******************************************************************
1659 Determine if a pattern contains any Microsoft wildcard characters.
1660 *******************************************************************/
1662 bool ms_has_wild(const char *s)
1664 char c;
1666 if (lp_posix_pathnames()) {
1667 /* With posix pathnames no characters are wild. */
1668 return False;
1671 while ((c = *s++)) {
1672 switch (c) {
1673 case '*':
1674 case '?':
1675 case '<':
1676 case '>':
1677 case '"':
1678 return True;
1681 return False;
1684 bool ms_has_wild_w(const smb_ucs2_t *s)
1686 smb_ucs2_t c;
1687 if (!s) return False;
1688 while ((c = *s++)) {
1689 switch (c) {
1690 case UCS2_CHAR('*'):
1691 case UCS2_CHAR('?'):
1692 case UCS2_CHAR('<'):
1693 case UCS2_CHAR('>'):
1694 case UCS2_CHAR('"'):
1695 return True;
1698 return False;
1701 /*******************************************************************
1702 A wrapper that handles case sensitivity and the special handling
1703 of the ".." name.
1704 *******************************************************************/
1706 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1708 if (ISDOTDOT(string))
1709 string = ".";
1710 if (ISDOT(pattern))
1711 return False;
1713 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1716 /*******************************************************************
1717 A wrapper that handles case sensitivity and the special handling
1718 of the ".." name. Varient that is only called by old search code which requires
1719 pattern translation.
1720 *******************************************************************/
1722 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1724 if (ISDOTDOT(string))
1725 string = ".";
1726 if (ISDOT(pattern))
1727 return False;
1729 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1732 /*******************************************************************
1733 A wrapper that handles a list of patters and calls mask_match()
1734 on each. Returns True if any of the patterns match.
1735 *******************************************************************/
1737 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1739 while (listLen-- > 0) {
1740 if (mask_match(string, *list++, is_case_sensitive))
1741 return True;
1743 return False;
1746 /*********************************************************
1747 Recursive routine that is called by unix_wild_match.
1748 *********************************************************/
1750 static bool unix_do_match(const char *regexp, const char *str)
1752 const char *p;
1754 for( p = regexp; *p && *str; ) {
1756 switch(*p) {
1757 case '?':
1758 str++;
1759 p++;
1760 break;
1762 case '*':
1765 * Look for a character matching
1766 * the one after the '*'.
1768 p++;
1769 if(!*p)
1770 return true; /* Automatic match */
1771 while(*str) {
1773 while(*str && (*p != *str))
1774 str++;
1777 * Patch from weidel@multichart.de. In the case of the regexp
1778 * '*XX*' we want to ensure there are at least 2 'X' characters
1779 * in the string after the '*' for a match to be made.
1783 int matchcount=0;
1786 * Eat all the characters that match, but count how many there were.
1789 while(*str && (*p == *str)) {
1790 str++;
1791 matchcount++;
1795 * Now check that if the regexp had n identical characters that
1796 * matchcount had at least that many matches.
1799 while ( *(p+1) && (*(p+1) == *p)) {
1800 p++;
1801 matchcount--;
1804 if ( matchcount <= 0 )
1805 return false;
1808 str--; /* We've eaten the match char after the '*' */
1810 if(unix_do_match(p, str))
1811 return true;
1813 if(!*str)
1814 return false;
1815 else
1816 str++;
1818 return false;
1820 default:
1821 if(*str != *p)
1822 return false;
1823 str++;
1824 p++;
1825 break;
1829 if(!*p && !*str)
1830 return true;
1832 if (!*p && str[0] == '.' && str[1] == 0)
1833 return true;
1835 if (!*str && *p == '?') {
1836 while (*p == '?')
1837 p++;
1838 return(!*p);
1841 if(!*str && (*p == '*' && p[1] == '\0'))
1842 return true;
1844 return false;
1847 /*******************************************************************
1848 Simple case insensitive interface to a UNIX wildcard matcher.
1849 Returns True if match, False if not.
1850 *******************************************************************/
1852 bool unix_wild_match(const char *pattern, const char *string)
1854 TALLOC_CTX *ctx = talloc_stackframe();
1855 char *p2;
1856 char *s2;
1857 char *p;
1858 bool ret = false;
1860 p2 = talloc_strdup(ctx,pattern);
1861 s2 = talloc_strdup(ctx,string);
1862 if (!p2 || !s2) {
1863 TALLOC_FREE(ctx);
1864 return false;
1866 strlower_m(p2);
1867 strlower_m(s2);
1869 /* Remove any *? and ** from the pattern as they are meaningless */
1870 for(p = p2; *p; p++) {
1871 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1872 memmove(&p[1], &p[2], strlen(&p[2])+1);
1876 if (strequal(p2,"*")) {
1877 TALLOC_FREE(ctx);
1878 return true;
1881 ret = unix_do_match(p2, s2);
1882 TALLOC_FREE(ctx);
1883 return ret;
1886 /**********************************************************************
1887 Converts a name to a fully qualified domain name.
1888 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1889 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1890 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1891 ***********************************************************************/
1893 bool name_to_fqdn(fstring fqdn, const char *name)
1895 char *full = NULL;
1896 struct hostent *hp = gethostbyname(name);
1898 if (!hp || !hp->h_name || !*hp->h_name) {
1899 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1900 fstrcpy(fqdn, name);
1901 return false;
1904 /* Find out if the fqdn is returned as an alias
1905 * to cope with /etc/hosts files where the first
1906 * name is not the fqdn but the short name */
1907 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1908 int i;
1909 for (i = 0; hp->h_aliases[i]; i++) {
1910 if (strchr_m(hp->h_aliases[i], '.')) {
1911 full = hp->h_aliases[i];
1912 break;
1916 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1917 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1918 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1919 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1920 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1921 full = hp->h_name;
1923 if (!full) {
1924 full = hp->h_name;
1927 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1928 fstrcpy(fqdn, full);
1929 return true;
1932 /**********************************************************************
1933 Append a DATA_BLOB to a talloc'ed object
1934 ***********************************************************************/
1936 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1938 size_t old_size = 0;
1939 char *result;
1941 if (blob.length == 0) {
1942 return buf;
1945 if (buf != NULL) {
1946 old_size = talloc_get_size(buf);
1949 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1950 if (result == NULL) {
1951 return NULL;
1954 memcpy(result + old_size, blob.data, blob.length);
1955 return result;
1958 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1960 switch (share_access & ~FILE_SHARE_DELETE) {
1961 case FILE_SHARE_NONE:
1962 return DENY_ALL;
1963 case FILE_SHARE_READ:
1964 return DENY_WRITE;
1965 case FILE_SHARE_WRITE:
1966 return DENY_READ;
1967 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1968 return DENY_NONE;
1970 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1971 return DENY_DOS;
1972 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1973 return DENY_FCB;
1976 return (uint32)-1;
1979 pid_t procid_to_pid(const struct server_id *proc)
1981 return proc->pid;
1984 static uint32 my_vnn = NONCLUSTER_VNN;
1986 void set_my_vnn(uint32 vnn)
1988 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn));
1989 my_vnn = vnn;
1992 uint32 get_my_vnn(void)
1994 return my_vnn;
1997 static uint64_t my_unique_id = 0;
1999 void set_my_unique_id(uint64_t unique_id)
2001 my_unique_id = unique_id;
2004 struct server_id pid_to_procid(pid_t pid)
2006 struct server_id result;
2007 result.pid = pid;
2008 result.task_id = 0;
2009 result.unique_id = my_unique_id;
2010 result.vnn = my_vnn;
2011 return result;
2014 struct server_id procid_self(void)
2016 return pid_to_procid(getpid());
2019 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2021 if (p1->pid != p2->pid)
2022 return False;
2023 if (p1->task_id != p2->task_id)
2024 return False;
2025 if (p1->vnn != p2->vnn)
2026 return False;
2027 return True;
2030 bool cluster_id_equal(const struct server_id *id1,
2031 const struct server_id *id2)
2033 return procid_equal(id1, id2);
2036 bool procid_is_me(const struct server_id *pid)
2038 if (pid->pid != getpid())
2039 return False;
2040 if (pid->task_id != 0)
2041 return False;
2042 if (pid->vnn != my_vnn)
2043 return False;
2044 return True;
2047 struct server_id interpret_pid(const char *pid_string)
2049 struct server_id result;
2050 unsigned long long pid;
2051 unsigned int vnn, task_id = 0;
2053 ZERO_STRUCT(result);
2055 /* We accept various forms with 1, 2 or 3 component forms
2056 * because the server_id_str() can print different forms, and
2057 * we want backwards compatibility for scripts that may call
2058 * smbclient. */
2059 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2060 result.vnn = vnn;
2061 result.pid = pid;
2062 result.task_id = task_id;
2063 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2064 result.vnn = vnn;
2065 result.pid = pid;
2066 result.task_id = 0;
2067 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2068 result.vnn = get_my_vnn();
2069 result.pid = pid;
2070 result.task_id = task_id;
2071 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2072 result.vnn = get_my_vnn();
2073 result.pid = pid;
2074 } else {
2075 result.vnn = NONCLUSTER_VNN;
2076 result.pid = (uint64_t)-1;
2078 return result;
2081 char *procid_str_static(const struct server_id *pid)
2083 return server_id_str(talloc_tos(), pid);
2086 bool procid_valid(const struct server_id *pid)
2088 return (pid->pid != (uint64_t)-1);
2091 bool procid_is_local(const struct server_id *pid)
2093 return pid->vnn == my_vnn;
2096 /****************************************************************
2097 Check if an offset into a buffer is safe.
2098 If this returns True it's safe to indirect into the byte at
2099 pointer ptr+off.
2100 ****************************************************************/
2102 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2104 const char *end_base = buf_base + buf_len;
2105 char *end_ptr = ptr + off;
2107 if (!buf_base || !ptr) {
2108 return False;
2111 if (end_base < buf_base || end_ptr < ptr) {
2112 return False; /* wrap. */
2115 if (end_ptr < end_base) {
2116 return True;
2118 return False;
2121 /****************************************************************
2122 Return a safe pointer into a buffer, or NULL.
2123 ****************************************************************/
2125 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2127 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2128 ptr + off : NULL;
2131 /****************************************************************
2132 Return a safe pointer into a string within a buffer, or NULL.
2133 ****************************************************************/
2135 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2137 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2138 return NULL;
2140 /* Check if a valid string exists at this offset. */
2141 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2142 return NULL;
2144 return ptr + off;
2147 /****************************************************************
2148 Return an SVAL at a pointer, or failval if beyond the end.
2149 ****************************************************************/
2151 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2154 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2155 * NOT ptr[2].
2157 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2158 return failval;
2160 return SVAL(ptr,off);
2163 /****************************************************************
2164 Return an IVAL at a pointer, or failval if beyond the end.
2165 ****************************************************************/
2167 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2170 * Note we use off+3 here, not off+4 as IVAL accesses
2171 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2173 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2174 return failval;
2176 return IVAL(ptr,off);
2179 /****************************************************************
2180 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2181 call (they take care of winbind separator and other winbind specific settings).
2182 ****************************************************************/
2184 void split_domain_user(TALLOC_CTX *mem_ctx,
2185 const char *full_name,
2186 char **domain,
2187 char **user)
2189 const char *p = NULL;
2191 p = strchr_m(full_name, '\\');
2193 if (p != NULL) {
2194 *domain = talloc_strndup(mem_ctx, full_name,
2195 PTR_DIFF(p, full_name));
2196 *user = talloc_strdup(mem_ctx, p+1);
2197 } else {
2198 *domain = talloc_strdup(mem_ctx, "");
2199 *user = talloc_strdup(mem_ctx, full_name);
2203 /****************************************************************
2204 strip off leading '\\' from a hostname
2205 ****************************************************************/
2207 const char *strip_hostname(const char *s)
2209 if (!s) {
2210 return NULL;
2213 if (strlen_m(s) < 3) {
2214 return s;
2217 if (s[0] == '\\') s++;
2218 if (s[0] == '\\') s++;
2220 return s;
2223 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2224 struct tevent_context *ev,
2225 NTSTATUS *status)
2227 bool ret = tevent_req_poll(req, ev);
2228 if (!ret) {
2229 *status = map_nt_error_from_unix(errno);
2231 return ret;
2234 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2236 if (!NT_STATUS_IS_OK(err1)) {
2237 *result = err1;
2238 return true;
2240 if (!NT_STATUS_IS_OK(err2)) {
2241 *result = err2;
2242 return true;
2244 return false;
2247 int timeval_to_msec(struct timeval t)
2249 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2252 /*******************************************************************
2253 Check a given DOS pathname is valid for a share.
2254 ********************************************************************/
2256 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2258 char *ptr = NULL;
2260 if (!dos_pathname) {
2261 return NULL;
2264 ptr = talloc_strdup(ctx, dos_pathname);
2265 if (!ptr) {
2266 return NULL;
2268 /* Convert any '\' paths to '/' */
2269 unix_format(ptr);
2270 ptr = unix_clean_name(ctx, ptr);
2271 if (!ptr) {
2272 return NULL;
2275 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2276 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2277 ptr += 2;
2279 /* Only absolute paths allowed. */
2280 if (*ptr != '/')
2281 return NULL;
2283 return ptr;
2286 /*******************************************************************
2287 Return True if the filename is one of the special executable types.
2288 ********************************************************************/
2290 bool is_executable(const char *fname)
2292 if ((fname = strrchr_m(fname,'.'))) {
2293 if (strequal(fname,".com") ||
2294 strequal(fname,".dll") ||
2295 strequal(fname,".exe") ||
2296 strequal(fname,".sym")) {
2297 return True;
2300 return False;
2303 /****************************************************************************
2304 Open a file with a share mode - old openX method - map into NTCreate.
2305 ****************************************************************************/
2307 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2308 int deny_mode, int open_func,
2309 uint32 *paccess_mask,
2310 uint32 *pshare_mode,
2311 uint32 *pcreate_disposition,
2312 uint32 *pcreate_options,
2313 uint32_t *pprivate_flags)
2315 uint32 access_mask;
2316 uint32 share_mode;
2317 uint32 create_disposition;
2318 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2319 uint32_t private_flags = 0;
2321 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2322 "open_func = 0x%x\n",
2323 smb_base_fname, (unsigned int)deny_mode,
2324 (unsigned int)open_func ));
2326 /* Create the NT compatible access_mask. */
2327 switch (GET_OPENX_MODE(deny_mode)) {
2328 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2329 case DOS_OPEN_RDONLY:
2330 access_mask = FILE_GENERIC_READ;
2331 break;
2332 case DOS_OPEN_WRONLY:
2333 access_mask = FILE_GENERIC_WRITE;
2334 break;
2335 case DOS_OPEN_RDWR:
2336 case DOS_OPEN_FCB:
2337 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2338 break;
2339 default:
2340 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2341 (unsigned int)GET_OPENX_MODE(deny_mode)));
2342 return False;
2345 /* Create the NT compatible create_disposition. */
2346 switch (open_func) {
2347 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2348 create_disposition = FILE_CREATE;
2349 break;
2351 case OPENX_FILE_EXISTS_OPEN:
2352 create_disposition = FILE_OPEN;
2353 break;
2355 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2356 create_disposition = FILE_OPEN_IF;
2357 break;
2359 case OPENX_FILE_EXISTS_TRUNCATE:
2360 create_disposition = FILE_OVERWRITE;
2361 break;
2363 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2364 create_disposition = FILE_OVERWRITE_IF;
2365 break;
2367 default:
2368 /* From samba4 - to be confirmed. */
2369 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2370 create_disposition = FILE_CREATE;
2371 break;
2373 DEBUG(10,("map_open_params_to_ntcreate: bad "
2374 "open_func 0x%x\n", (unsigned int)open_func));
2375 return False;
2378 /* Create the NT compatible share modes. */
2379 switch (GET_DENY_MODE(deny_mode)) {
2380 case DENY_ALL:
2381 share_mode = FILE_SHARE_NONE;
2382 break;
2384 case DENY_WRITE:
2385 share_mode = FILE_SHARE_READ;
2386 break;
2388 case DENY_READ:
2389 share_mode = FILE_SHARE_WRITE;
2390 break;
2392 case DENY_NONE:
2393 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2394 break;
2396 case DENY_DOS:
2397 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2398 if (is_executable(smb_base_fname)) {
2399 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2400 } else {
2401 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2402 share_mode = FILE_SHARE_READ;
2403 } else {
2404 share_mode = FILE_SHARE_NONE;
2407 break;
2409 case DENY_FCB:
2410 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2411 share_mode = FILE_SHARE_NONE;
2412 break;
2414 default:
2415 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2416 (unsigned int)GET_DENY_MODE(deny_mode) ));
2417 return False;
2420 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2421 "share_mode = 0x%x, create_disposition = 0x%x, "
2422 "create_options = 0x%x private_flags = 0x%x\n",
2423 smb_base_fname,
2424 (unsigned int)access_mask,
2425 (unsigned int)share_mode,
2426 (unsigned int)create_disposition,
2427 (unsigned int)create_options,
2428 (unsigned int)private_flags));
2430 if (paccess_mask) {
2431 *paccess_mask = access_mask;
2433 if (pshare_mode) {
2434 *pshare_mode = share_mode;
2436 if (pcreate_disposition) {
2437 *pcreate_disposition = create_disposition;
2439 if (pcreate_options) {
2440 *pcreate_options = create_options;
2442 if (pprivate_flags) {
2443 *pprivate_flags = private_flags;
2446 return True;