s3: make linking of pthreadpooltest work on more platforms
[Samba/gbeck.git] / source3 / lib / util.c
blob689d41ed17c3bd907f998b5eb3a4028cbc788eeb
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 /* Max allowable allococation - 256mb - 0x10000000 */
35 #define MAX_ALLOC_SIZE (1024*1024*256)
37 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
38 #ifdef WITH_NISPLUS_HOME
39 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
41 * The following lines are needed due to buggy include files
42 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
43 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
44 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
45 * an enum in /usr/include/rpcsvc/nis.h.
48 #if defined(GROUP)
49 #undef GROUP
50 #endif
52 #if defined(GROUP_OBJ)
53 #undef GROUP_OBJ
54 #endif
56 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
58 #include <rpcsvc/nis.h>
60 #endif /* WITH_NISPLUS_HOME */
61 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
63 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
65 enum protocol_types get_Protocol(void)
67 return Protocol;
70 void set_Protocol(enum protocol_types p)
72 Protocol = p;
75 static enum remote_arch_types ra_type = RA_UNKNOWN;
77 void gfree_all( void )
79 gfree_names();
80 gfree_loadparm();
81 gfree_charcnv();
82 gfree_interfaces();
83 gfree_debugsyms();
86 /*******************************************************************
87 Check if a file exists - call vfs_file_exist for samba files.
88 ********************************************************************/
90 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
91 bool fake_dir_create_times)
93 SMB_STRUCT_STAT st;
94 if (!sbuf)
95 sbuf = &st;
97 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
98 return(False);
100 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
103 /*******************************************************************
104 Check if a unix domain socket exists - call vfs_file_exist for samba files.
105 ********************************************************************/
107 bool socket_exist(const char *fname)
109 SMB_STRUCT_STAT st;
110 if (sys_stat(fname, &st, false) != 0)
111 return(False);
113 return S_ISSOCK(st.st_ex_mode);
116 /*******************************************************************
117 Returns the size in bytes of the named given the stat struct.
118 ********************************************************************/
120 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
122 return sbuf->st_ex_size;
125 /*******************************************************************
126 Returns the size in bytes of the named file.
127 ********************************************************************/
129 SMB_OFF_T get_file_size(char *file_name)
131 SMB_STRUCT_STAT buf;
132 buf.st_ex_size = 0;
133 if (sys_stat(file_name, &buf, false) != 0)
134 return (SMB_OFF_T)-1;
135 return get_file_size_stat(&buf);
138 /*******************************************************************
139 Show a smb message structure.
140 ********************************************************************/
142 void show_msg(const char *buf)
144 int i;
145 int bcc=0;
147 if (!DEBUGLVL(5))
148 return;
150 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
151 smb_len(buf),
152 (int)CVAL(buf,smb_com),
153 (int)CVAL(buf,smb_rcls),
154 (int)CVAL(buf,smb_reh),
155 (int)SVAL(buf,smb_err),
156 (int)CVAL(buf,smb_flg),
157 (int)SVAL(buf,smb_flg2)));
158 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
159 (int)SVAL(buf,smb_tid),
160 (int)SVAL(buf,smb_pid),
161 (int)SVAL(buf,smb_uid),
162 (int)SVAL(buf,smb_mid)));
163 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
165 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
166 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
167 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
169 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
171 DEBUGADD(5,("smb_bcc=%d\n",bcc));
173 if (DEBUGLEVEL < 10)
174 return;
176 if (DEBUGLEVEL < 50)
177 bcc = MIN(bcc, 512);
179 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
182 /*******************************************************************
183 Set the length and marker of an encrypted smb packet.
184 ********************************************************************/
186 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
188 _smb_setlen(buf,len);
190 SCVAL(buf,4,0xFF);
191 SCVAL(buf,5,'E');
192 SSVAL(buf,6,enc_ctx_num);
195 /*******************************************************************
196 Set the length and marker of an smb packet.
197 ********************************************************************/
199 void smb_setlen(char *buf,int len)
201 _smb_setlen(buf,len);
203 SCVAL(buf,4,0xFF);
204 SCVAL(buf,5,'S');
205 SCVAL(buf,6,'M');
206 SCVAL(buf,7,'B');
209 /*******************************************************************
210 Setup only the byte count for a smb message.
211 ********************************************************************/
213 int set_message_bcc(char *buf,int num_bytes)
215 int num_words = CVAL(buf,smb_wct);
216 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
217 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
218 return (smb_size + num_words*2 + num_bytes);
221 /*******************************************************************
222 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
223 Return the bytes added
224 ********************************************************************/
226 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
228 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
229 uint8 *tmp;
231 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
232 DEBUG(0, ("talloc failed\n"));
233 return -1;
235 *outbuf = tmp;
237 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
238 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
239 return blob.length;
242 /*******************************************************************
243 Reduce a file name, removing .. elements.
244 ********************************************************************/
246 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
248 char *p = NULL;
249 char *str = NULL;
251 DEBUG(3,("dos_clean_name [%s]\n",s));
253 /* remove any double slashes */
254 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
255 if (!str) {
256 return NULL;
259 /* Remove leading .\\ characters */
260 if(strncmp(str, ".\\", 2) == 0) {
261 trim_string(str, ".\\", NULL);
262 if(*str == 0) {
263 str = talloc_strdup(ctx, ".\\");
264 if (!str) {
265 return NULL;
270 while ((p = strstr_m(str,"\\..\\")) != NULL) {
271 char *s1;
273 *p = 0;
274 s1 = p+3;
276 if ((p=strrchr_m(str,'\\')) != NULL) {
277 *p = 0;
278 } else {
279 *str = 0;
281 str = talloc_asprintf(ctx,
282 "%s%s",
283 str,
284 s1);
285 if (!str) {
286 return NULL;
290 trim_string(str,NULL,"\\..");
291 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
294 /*******************************************************************
295 Reduce a file name, removing .. elements.
296 ********************************************************************/
298 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
300 char *p = NULL;
301 char *str = NULL;
303 DEBUG(3,("unix_clean_name [%s]\n",s));
305 /* remove any double slashes */
306 str = talloc_all_string_sub(ctx, s, "//","/");
307 if (!str) {
308 return NULL;
311 /* Remove leading ./ characters */
312 if(strncmp(str, "./", 2) == 0) {
313 trim_string(str, "./", NULL);
314 if(*str == 0) {
315 str = talloc_strdup(ctx, "./");
316 if (!str) {
317 return NULL;
322 while ((p = strstr_m(str,"/../")) != NULL) {
323 char *s1;
325 *p = 0;
326 s1 = p+3;
328 if ((p=strrchr_m(str,'/')) != NULL) {
329 *p = 0;
330 } else {
331 *str = 0;
333 str = talloc_asprintf(ctx,
334 "%s%s",
335 str,
336 s1);
337 if (!str) {
338 return NULL;
342 trim_string(str,NULL,"/..");
343 return talloc_all_string_sub(ctx, str, "/./", "/");
346 char *clean_name(TALLOC_CTX *ctx, const char *s)
348 char *str = dos_clean_name(ctx, s);
349 if (!str) {
350 return NULL;
352 return unix_clean_name(ctx, str);
355 /*******************************************************************
356 Write data into an fd at a given offset. Ignore seek errors.
357 ********************************************************************/
359 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
361 size_t total=0;
362 ssize_t ret;
364 if (pos == (SMB_OFF_T)-1) {
365 return write_data(fd, buffer, N);
367 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
368 while (total < N) {
369 ret = sys_pwrite(fd,buffer + total,N - total, pos);
370 if (ret == -1 && errno == ESPIPE) {
371 return write_data(fd, buffer + total,N - total);
373 if (ret == -1) {
374 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
375 return -1;
377 if (ret == 0) {
378 return total;
380 total += ret;
381 pos += ret;
383 return (ssize_t)total;
384 #else
385 /* Use lseek and write_data. */
386 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
387 if (errno != ESPIPE) {
388 return -1;
391 return write_data(fd, buffer, N);
392 #endif
396 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
397 struct event_context *ev_ctx,
398 struct server_id id,
399 bool parent_longlived)
401 NTSTATUS status = NT_STATUS_OK;
403 /* Reset the state of the random
404 * number generation system, so
405 * children do not get the same random
406 * numbers as each other */
407 set_need_random_reseed();
409 /* tdb needs special fork handling */
410 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
411 DEBUG(0,("tdb_reopen_all failed.\n"));
412 status = NT_STATUS_OPEN_FAILED;
413 goto done;
416 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
417 smb_panic(__location__ ": Failed to re-initialise event context");
420 if (msg_ctx) {
422 * For clustering, we need to re-init our ctdbd connection after the
423 * fork
425 status = messaging_reinit(msg_ctx, id);
426 if (!NT_STATUS_IS_OK(status)) {
427 DEBUG(0,("messaging_reinit() failed: %s\n",
428 nt_errstr(status)));
431 done:
432 return status;
435 /****************************************************************************
436 (Hopefully) efficient array append.
437 ****************************************************************************/
439 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
440 void *element, void *_array, uint32 *num_elements,
441 ssize_t *array_size)
443 void **array = (void **)_array;
445 if (*array_size < 0) {
446 return;
449 if (*array == NULL) {
450 if (*array_size == 0) {
451 *array_size = 128;
454 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
455 goto error;
458 *array = TALLOC(mem_ctx, element_size * (*array_size));
459 if (*array == NULL) {
460 goto error;
464 if (*num_elements == *array_size) {
465 *array_size *= 2;
467 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
468 goto error;
471 *array = TALLOC_REALLOC(mem_ctx, *array,
472 element_size * (*array_size));
474 if (*array == NULL) {
475 goto error;
479 memcpy((char *)(*array) + element_size*(*num_elements),
480 element, element_size);
481 *num_elements += 1;
483 return;
485 error:
486 *num_elements = 0;
487 *array_size = -1;
490 /****************************************************************************
491 Get my own domain name, or "" if we have none.
492 ****************************************************************************/
494 char *get_mydnsdomname(TALLOC_CTX *ctx)
496 const char *domname;
497 char *p;
499 domname = get_mydnsfullname();
500 if (!domname) {
501 return NULL;
504 p = strchr_m(domname, '.');
505 if (p) {
506 p++;
507 return talloc_strdup(ctx, p);
508 } else {
509 return talloc_strdup(ctx, "");
513 /****************************************************************************
514 Interpret a protocol description string, with a default.
515 ****************************************************************************/
517 int interpret_protocol(const char *str,int def)
519 if (strequal(str,"NT1"))
520 return(PROTOCOL_NT1);
521 if (strequal(str,"LANMAN2"))
522 return(PROTOCOL_LANMAN2);
523 if (strequal(str,"LANMAN1"))
524 return(PROTOCOL_LANMAN1);
525 if (strequal(str,"CORE"))
526 return(PROTOCOL_CORE);
527 if (strequal(str,"COREPLUS"))
528 return(PROTOCOL_COREPLUS);
529 if (strequal(str,"CORE+"))
530 return(PROTOCOL_COREPLUS);
532 DEBUG(0,("Unrecognised protocol level %s\n",str));
534 return(def);
538 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
539 /******************************************************************
540 Remove any mount options such as -rsize=2048,wsize=2048 etc.
541 Based on a fix from <Thomas.Hepper@icem.de>.
542 Returns a malloc'ed string.
543 *******************************************************************/
545 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
547 if (*str == '-') {
548 const char *p = str;
549 while(*p && !isspace(*p))
550 p++;
551 while(*p && isspace(*p))
552 p++;
553 if(*p) {
554 return talloc_strdup(ctx, p);
557 return NULL;
560 /*******************************************************************
561 Patch from jkf@soton.ac.uk
562 Split Luke's automount_server into YP lookup and string splitter
563 so can easily implement automount_path().
564 Returns a malloc'ed string.
565 *******************************************************************/
567 #ifdef WITH_NISPLUS_HOME
568 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
570 char *value = NULL;
572 char *nis_map = (char *)lp_nis_home_map_name();
574 char buffer[NIS_MAXATTRVAL + 1];
575 nis_result *result;
576 nis_object *object;
577 entry_obj *entry;
579 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
580 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
582 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
583 if (result->status != NIS_SUCCESS) {
584 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
585 } else {
586 object = result->objects.objects_val;
587 if (object->zo_data.zo_type == ENTRY_OBJ) {
588 entry = &object->zo_data.objdata_u.en_data;
589 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
590 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
592 value = talloc_strdup(ctx,
593 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
594 if (!value) {
595 nis_freeresult(result);
596 return NULL;
598 value = talloc_string_sub(ctx,
599 value,
600 "&",
601 user_name);
605 nis_freeresult(result);
607 if (value) {
608 value = strip_mount_options(ctx, value);
609 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
610 user_name, value));
612 return value;
614 #else /* WITH_NISPLUS_HOME */
616 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
618 char *value = NULL;
620 int nis_error; /* returned by yp all functions */
621 char *nis_result; /* yp_match inits this */
622 int nis_result_len; /* and set this */
623 char *nis_domain; /* yp_get_default_domain inits this */
624 char *nis_map = (char *)lp_nis_home_map_name();
626 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
627 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
628 return NULL;
631 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
633 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
634 strlen(user_name), &nis_result,
635 &nis_result_len)) == 0) {
636 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
637 nis_result[nis_result_len] = '\0';
639 value = talloc_strdup(ctx, nis_result);
640 if (!value) {
641 return NULL;
643 value = strip_mount_options(ctx, value);
644 } else if(nis_error == YPERR_KEY) {
645 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
646 user_name, nis_map));
647 DEBUG(3, ("using defaults for server and home directory\n"));
648 } else {
649 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
650 yperr_string(nis_error), user_name, nis_map));
653 if (value) {
654 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
656 return value;
658 #endif /* WITH_NISPLUS_HOME */
659 #endif
661 /****************************************************************************
662 Check if a process exists. Does this work on all unixes?
663 ****************************************************************************/
665 bool process_exists(const struct server_id pid)
667 if (procid_is_me(&pid)) {
668 return True;
671 if (procid_is_local(&pid)) {
672 return (kill(pid.pid,0) == 0 || errno != ESRCH);
675 #ifdef CLUSTER_SUPPORT
676 return ctdbd_process_exists(messaging_ctdbd_connection(),
677 pid.vnn, pid.pid);
678 #else
679 return False;
680 #endif
683 /*******************************************************************
684 Convert a uid into a user name.
685 ********************************************************************/
687 const char *uidtoname(uid_t uid)
689 TALLOC_CTX *ctx = talloc_tos();
690 char *name = NULL;
691 struct passwd *pass = NULL;
693 pass = getpwuid_alloc(ctx,uid);
694 if (pass) {
695 name = talloc_strdup(ctx,pass->pw_name);
696 TALLOC_FREE(pass);
697 } else {
698 name = talloc_asprintf(ctx,
699 "%ld",
700 (long int)uid);
702 return name;
705 /*******************************************************************
706 Convert a gid into a group name.
707 ********************************************************************/
709 char *gidtoname(gid_t gid)
711 struct group *grp;
713 grp = getgrgid(gid);
714 if (grp) {
715 return talloc_strdup(talloc_tos(), grp->gr_name);
717 else {
718 return talloc_asprintf(talloc_tos(),
719 "%d",
720 (int)gid);
724 /*******************************************************************
725 Convert a user name into a uid.
726 ********************************************************************/
728 uid_t nametouid(const char *name)
730 struct passwd *pass;
731 char *p;
732 uid_t u;
734 pass = Get_Pwnam_alloc(talloc_tos(), name);
735 if (pass) {
736 u = pass->pw_uid;
737 TALLOC_FREE(pass);
738 return u;
741 u = (uid_t)strtol(name, &p, 0);
742 if ((p != name) && (*p == '\0'))
743 return u;
745 return (uid_t)-1;
748 /*******************************************************************
749 Convert a name to a gid_t if possible. Return -1 if not a group.
750 ********************************************************************/
752 gid_t nametogid(const char *name)
754 struct group *grp;
755 char *p;
756 gid_t g;
758 g = (gid_t)strtol(name, &p, 0);
759 if ((p != name) && (*p == '\0'))
760 return g;
762 grp = sys_getgrnam(name);
763 if (grp)
764 return(grp->gr_gid);
765 return (gid_t)-1;
768 /*******************************************************************
769 Something really nasty happened - panic !
770 ********************************************************************/
772 void smb_panic_s3(const char *why)
774 char *cmd;
775 int result;
777 DEBUG(0,("PANIC (pid %llu): %s\n",
778 (unsigned long long)sys_getpid(), why));
779 log_stack_trace();
781 cmd = lp_panic_action();
782 if (cmd && *cmd) {
783 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
784 result = system(cmd);
786 if (result == -1)
787 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
788 strerror(errno)));
789 else
790 DEBUG(0, ("smb_panic(): action returned status %d\n",
791 WEXITSTATUS(result)));
794 dump_core();
797 /*******************************************************************
798 Print a backtrace of the stack to the debug log. This function
799 DELIBERATELY LEAKS MEMORY. The expectation is that you should
800 exit shortly after calling it.
801 ********************************************************************/
803 #ifdef HAVE_LIBUNWIND_H
804 #include <libunwind.h>
805 #endif
807 #ifdef HAVE_EXECINFO_H
808 #include <execinfo.h>
809 #endif
811 #ifdef HAVE_LIBEXC_H
812 #include <libexc.h>
813 #endif
815 void log_stack_trace(void)
817 #ifdef HAVE_LIBUNWIND
818 /* Try to use libunwind before any other technique since on ia64
819 * libunwind correctly walks the stack in more circumstances than
820 * backtrace.
822 unw_cursor_t cursor;
823 unw_context_t uc;
824 unsigned i = 0;
826 char procname[256];
827 unw_word_t ip, sp, off;
829 procname[sizeof(procname) - 1] = '\0';
831 if (unw_getcontext(&uc) != 0) {
832 goto libunwind_failed;
835 if (unw_init_local(&cursor, &uc) != 0) {
836 goto libunwind_failed;
839 DEBUG(0, ("BACKTRACE:\n"));
841 do {
842 ip = sp = 0;
843 unw_get_reg(&cursor, UNW_REG_IP, &ip);
844 unw_get_reg(&cursor, UNW_REG_SP, &sp);
846 switch (unw_get_proc_name(&cursor,
847 procname, sizeof(procname) - 1, &off) ) {
848 case 0:
849 /* Name found. */
850 case -UNW_ENOMEM:
851 /* Name truncated. */
852 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
853 i, procname, (long long)off,
854 (long long)ip, (long long) sp));
855 break;
856 default:
857 /* case -UNW_ENOINFO: */
858 /* case -UNW_EUNSPEC: */
859 /* No symbol name found. */
860 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
861 i, "<unknown symbol>",
862 (long long)ip, (long long) sp));
864 ++i;
865 } while (unw_step(&cursor) > 0);
867 return;
869 libunwind_failed:
870 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
872 #elif HAVE_BACKTRACE_SYMBOLS
873 void *backtrace_stack[BACKTRACE_STACK_SIZE];
874 size_t backtrace_size;
875 char **backtrace_strings;
877 /* get the backtrace (stack frames) */
878 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
879 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
881 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
882 (unsigned long)backtrace_size));
884 if (backtrace_strings) {
885 int i;
887 for (i = 0; i < backtrace_size; i++)
888 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
890 /* Leak the backtrace_strings, rather than risk what free() might do */
893 #elif HAVE_LIBEXC
895 /* The IRIX libexc library provides an API for unwinding the stack. See
896 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
897 * since we are about to abort anyway, it hardly matters.
900 #define NAMESIZE 32 /* Arbitrary */
902 __uint64_t addrs[BACKTRACE_STACK_SIZE];
903 char * names[BACKTRACE_STACK_SIZE];
904 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
906 int i;
907 int levels;
909 ZERO_ARRAY(addrs);
910 ZERO_ARRAY(names);
911 ZERO_ARRAY(namebuf);
913 /* We need to be root so we can open our /proc entry to walk
914 * our stack. It also helps when we want to dump core.
916 become_root();
918 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
919 names[i] = namebuf + (i * NAMESIZE);
922 levels = trace_back_stack(0, addrs, names,
923 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
925 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
926 for (i = 0; i < levels; i++) {
927 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
929 #undef NAMESIZE
931 #else
932 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
933 #endif
936 /*******************************************************************
937 A readdir wrapper which just returns the file name.
938 ********************************************************************/
940 const char *readdirname(SMB_STRUCT_DIR *p)
942 SMB_STRUCT_DIRENT *ptr;
943 char *dname;
945 if (!p)
946 return(NULL);
948 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
949 if (!ptr)
950 return(NULL);
952 dname = ptr->d_name;
954 #ifdef NEXT2
955 if (telldir(p) < 0)
956 return(NULL);
957 #endif
959 #ifdef HAVE_BROKEN_READDIR_NAME
960 /* using /usr/ucb/cc is BAD */
961 dname = dname - 2;
962 #endif
964 return talloc_strdup(talloc_tos(), dname);
967 /*******************************************************************
968 Utility function used to decide if the last component
969 of a path matches a (possibly wildcarded) entry in a namelist.
970 ********************************************************************/
972 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
974 const char *last_component;
976 /* if we have no list it's obviously not in the path */
977 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
978 return False;
981 DEBUG(8, ("is_in_path: %s\n", name));
983 /* Get the last component of the unix name. */
984 last_component = strrchr_m(name, '/');
985 if (!last_component) {
986 last_component = name;
987 } else {
988 last_component++; /* Go past '/' */
991 for(; namelist->name != NULL; namelist++) {
992 if(namelist->is_wild) {
993 if (mask_match(last_component, namelist->name, case_sensitive)) {
994 DEBUG(8,("is_in_path: mask match succeeded\n"));
995 return True;
997 } else {
998 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
999 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1000 DEBUG(8,("is_in_path: match succeeded\n"));
1001 return True;
1005 DEBUG(8,("is_in_path: match not found\n"));
1006 return False;
1009 /*******************************************************************
1010 Strip a '/' separated list into an array of
1011 name_compare_enties structures suitable for
1012 passing to is_in_path(). We do this for
1013 speed so we can pre-parse all the names in the list
1014 and don't do it for each call to is_in_path().
1015 We also check if the entry contains a wildcard to
1016 remove a potentially expensive call to mask_match
1017 if possible.
1018 ********************************************************************/
1020 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1022 char *name_end;
1023 char *namelist;
1024 char *nameptr;
1025 int num_entries = 0;
1026 int i;
1028 (*ppname_array) = NULL;
1030 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1031 return;
1033 namelist = talloc_strdup(talloc_tos(), namelist_in);
1034 if (namelist == NULL) {
1035 DEBUG(0,("set_namearray: talloc fail\n"));
1036 return;
1038 nameptr = namelist;
1040 /* We need to make two passes over the string. The
1041 first to count the number of elements, the second
1042 to split it.
1045 while(*nameptr) {
1046 if ( *nameptr == '/' ) {
1047 /* cope with multiple (useless) /s) */
1048 nameptr++;
1049 continue;
1051 /* anything left? */
1052 if ( *nameptr == '\0' )
1053 break;
1055 /* find the next '/' or consume remaining */
1056 name_end = strchr_m(nameptr, '/');
1057 if (name_end == NULL)
1058 name_end = (char *)nameptr + strlen(nameptr);
1060 /* next segment please */
1061 nameptr = name_end + 1;
1062 num_entries++;
1065 if(num_entries == 0) {
1066 talloc_free(namelist);
1067 return;
1070 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1071 DEBUG(0,("set_namearray: malloc fail\n"));
1072 talloc_free(namelist);
1073 return;
1076 /* Now copy out the names */
1077 nameptr = namelist;
1078 i = 0;
1079 while(*nameptr) {
1080 if ( *nameptr == '/' ) {
1081 /* cope with multiple (useless) /s) */
1082 nameptr++;
1083 continue;
1085 /* anything left? */
1086 if ( *nameptr == '\0' )
1087 break;
1089 /* find the next '/' or consume remaining */
1090 name_end = strchr_m(nameptr, '/');
1091 if (name_end)
1092 *name_end = '\0';
1093 else
1094 name_end = nameptr + strlen(nameptr);
1096 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1097 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1098 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1099 talloc_free(namelist);
1100 return;
1103 /* next segment please */
1104 nameptr = name_end + 1;
1105 i++;
1108 (*ppname_array)[i].name = NULL;
1110 talloc_free(namelist);
1111 return;
1114 #undef DBGC_CLASS
1115 #define DBGC_CLASS DBGC_LOCKING
1117 /****************************************************************************
1118 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1119 is dealt with in posix.c
1120 Returns True if we have information regarding this lock region (and returns
1121 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1122 ****************************************************************************/
1124 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1126 SMB_STRUCT_FLOCK lock;
1127 int ret;
1129 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1130 fd,(double)*poffset,(double)*pcount,*ptype));
1132 lock.l_type = *ptype;
1133 lock.l_whence = SEEK_SET;
1134 lock.l_start = *poffset;
1135 lock.l_len = *pcount;
1136 lock.l_pid = 0;
1138 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1140 if (ret == -1) {
1141 int sav = errno;
1142 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1143 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1144 errno = sav;
1145 return False;
1148 *ptype = lock.l_type;
1149 *poffset = lock.l_start;
1150 *pcount = lock.l_len;
1151 *ppid = lock.l_pid;
1153 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1154 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1155 return True;
1158 #undef DBGC_CLASS
1159 #define DBGC_CLASS DBGC_ALL
1161 /*******************************************************************
1162 Is the name specified one of my netbios names.
1163 Returns true if it is equal, false otherwise.
1164 ********************************************************************/
1166 bool is_myname(const char *s)
1168 int n;
1169 bool ret = False;
1171 for (n=0; my_netbios_names(n); n++) {
1172 if (strequal(my_netbios_names(n), s)) {
1173 ret=True;
1174 break;
1177 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1178 return(ret);
1181 /*******************************************************************
1182 Is the name specified our workgroup/domain.
1183 Returns true if it is equal, false otherwise.
1184 ********************************************************************/
1186 bool is_myworkgroup(const char *s)
1188 bool ret = False;
1190 if (strequal(s, lp_workgroup())) {
1191 ret=True;
1194 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1195 return(ret);
1198 /*******************************************************************
1199 we distinguish between 2K and XP by the "Native Lan Manager" string
1200 WinXP => "Windows 2002 5.1"
1201 WinXP 64bit => "Windows XP 5.2"
1202 Win2k => "Windows 2000 5.0"
1203 NT4 => "Windows NT 4.0"
1204 Win9x => "Windows 4.0"
1205 Windows 2003 doesn't set the native lan manager string but
1206 they do set the domain to "Windows 2003 5.2" (probably a bug).
1207 ********************************************************************/
1209 void ra_lanman_string( const char *native_lanman )
1211 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1212 set_remote_arch( RA_WINXP );
1213 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1214 set_remote_arch( RA_WINXP64 );
1215 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1216 set_remote_arch( RA_WIN2K3 );
1219 static const char *remote_arch_str;
1221 const char *get_remote_arch_str(void)
1223 if (!remote_arch_str) {
1224 return "UNKNOWN";
1226 return remote_arch_str;
1229 /*******************************************************************
1230 Set the horrid remote_arch string based on an enum.
1231 ********************************************************************/
1233 void set_remote_arch(enum remote_arch_types type)
1235 ra_type = type;
1236 switch( type ) {
1237 case RA_WFWG:
1238 remote_arch_str = "WfWg";
1239 break;
1240 case RA_OS2:
1241 remote_arch_str = "OS2";
1242 break;
1243 case RA_WIN95:
1244 remote_arch_str = "Win95";
1245 break;
1246 case RA_WINNT:
1247 remote_arch_str = "WinNT";
1248 break;
1249 case RA_WIN2K:
1250 remote_arch_str = "Win2K";
1251 break;
1252 case RA_WINXP:
1253 remote_arch_str = "WinXP";
1254 break;
1255 case RA_WINXP64:
1256 remote_arch_str = "WinXP64";
1257 break;
1258 case RA_WIN2K3:
1259 remote_arch_str = "Win2K3";
1260 break;
1261 case RA_VISTA:
1262 remote_arch_str = "Vista";
1263 break;
1264 case RA_SAMBA:
1265 remote_arch_str = "Samba";
1266 break;
1267 case RA_CIFSFS:
1268 remote_arch_str = "CIFSFS";
1269 break;
1270 case RA_OSX:
1271 remote_arch_str = "OSX";
1272 break;
1273 default:
1274 ra_type = RA_UNKNOWN;
1275 remote_arch_str = "UNKNOWN";
1276 break;
1279 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1280 remote_arch_str));
1283 /*******************************************************************
1284 Get the remote_arch type.
1285 ********************************************************************/
1287 enum remote_arch_types get_remote_arch(void)
1289 return ra_type;
1292 const char *tab_depth(int level, int depth)
1294 if( CHECK_DEBUGLVL(level) ) {
1295 dbgtext("%*s", depth*4, "");
1297 return "";
1300 /*****************************************************************************
1301 Provide a checksum on a string
1303 Input: s - the null-terminated character string for which the checksum
1304 will be calculated.
1306 Output: The checksum value calculated for s.
1307 *****************************************************************************/
1309 int str_checksum(const char *s)
1311 if (s == NULL)
1312 return 0;
1313 return hash(s, strlen(s), 0);
1316 /*****************************************************************
1317 Zero a memory area then free it. Used to catch bugs faster.
1318 *****************************************************************/
1320 void zero_free(void *p, size_t size)
1322 memset(p, 0, size);
1323 SAFE_FREE(p);
1326 /*****************************************************************
1327 Set our open file limit to a requested max and return the limit.
1328 *****************************************************************/
1330 int set_maxfiles(int requested_max)
1332 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1333 struct rlimit rlp;
1334 int saved_current_limit;
1336 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1337 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1338 strerror(errno) ));
1339 /* just guess... */
1340 return requested_max;
1344 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1345 * account for the extra fd we need
1346 * as well as the log files and standard
1347 * handles etc. Save the limit we want to set in case
1348 * we are running on an OS that doesn't support this limit (AIX)
1349 * which always returns RLIM_INFINITY for rlp.rlim_max.
1352 /* Try raising the hard (max) limit to the requested amount. */
1354 #if defined(RLIM_INFINITY)
1355 if (rlp.rlim_max != RLIM_INFINITY) {
1356 int orig_max = rlp.rlim_max;
1358 if ( rlp.rlim_max < requested_max )
1359 rlp.rlim_max = requested_max;
1361 /* This failing is not an error - many systems (Linux) don't
1362 support our default request of 10,000 open files. JRA. */
1364 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1365 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1366 (int)rlp.rlim_max, strerror(errno) ));
1368 /* Set failed - restore original value from get. */
1369 rlp.rlim_max = orig_max;
1372 #endif
1374 /* Now try setting the soft (current) limit. */
1376 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1378 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1379 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1380 (int)rlp.rlim_cur, strerror(errno) ));
1381 /* just guess... */
1382 return saved_current_limit;
1385 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1386 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1387 strerror(errno) ));
1388 /* just guess... */
1389 return saved_current_limit;
1392 #if defined(RLIM_INFINITY)
1393 if(rlp.rlim_cur == RLIM_INFINITY)
1394 return saved_current_limit;
1395 #endif
1397 if((int)rlp.rlim_cur > saved_current_limit)
1398 return saved_current_limit;
1400 return rlp.rlim_cur;
1401 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1403 * No way to know - just guess...
1405 return requested_max;
1406 #endif
1409 /*****************************************************************
1410 malloc that aborts with smb_panic on fail or zero size.
1411 *****************************************************************/
1413 void *smb_xmalloc_array(size_t size, unsigned int count)
1415 void *p;
1416 if (size == 0) {
1417 smb_panic("smb_xmalloc_array: called with zero size");
1419 if (count >= MAX_ALLOC_SIZE/size) {
1420 smb_panic("smb_xmalloc_array: alloc size too large");
1422 if ((p = SMB_MALLOC(size*count)) == NULL) {
1423 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1424 (unsigned long)size, (unsigned long)count));
1425 smb_panic("smb_xmalloc_array: malloc failed");
1427 return p;
1431 vasprintf that aborts on malloc fail
1434 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1436 int n;
1437 va_list ap2;
1439 va_copy(ap2, ap);
1441 n = vasprintf(ptr, format, ap2);
1442 va_end(ap2);
1443 if (n == -1 || ! *ptr) {
1444 smb_panic("smb_xvasprintf: out of memory");
1446 return n;
1449 /*****************************************************************
1450 Get local hostname and cache result.
1451 *****************************************************************/
1453 char *myhostname(void)
1455 static char *ret;
1456 if (ret == NULL) {
1457 ret = get_myname(NULL);
1459 return ret;
1462 /*****************************************************************
1463 Get local hostname and cache result.
1464 *****************************************************************/
1466 char *myhostname_upper(void)
1468 char *name;
1469 static char *ret;
1470 if (ret == NULL) {
1471 name = get_myname(talloc_tos());
1472 ret = strupper_talloc(NULL, name);
1473 talloc_free(name);
1475 return ret;
1479 * @brief Returns an absolute path to a file concatenating the provided
1480 * @a rootpath and @a basename
1482 * @param name Filename, relative to @a rootpath
1484 * @retval Pointer to a string containing the full path.
1487 static char *xx_path(const char *name, const char *rootpath)
1489 char *fname = NULL;
1491 fname = talloc_strdup(talloc_tos(), rootpath);
1492 if (!fname) {
1493 return NULL;
1495 trim_string(fname,"","/");
1497 if (!directory_exist(fname)) {
1498 if (!mkdir(fname,0755))
1499 DEBUG(1, ("Unable to create directory %s for file %s. "
1500 "Error was %s\n", fname, name, strerror(errno)));
1503 return talloc_asprintf(talloc_tos(),
1504 "%s/%s",
1505 fname,
1506 name);
1510 * @brief Returns an absolute path to a file in the Samba lock directory.
1512 * @param name File to find, relative to LOCKDIR.
1514 * @retval Pointer to a talloc'ed string containing the full path.
1517 char *lock_path(const char *name)
1519 return xx_path(name, lp_lockdir());
1523 * @brief Returns an absolute path to a file in the Samba pid directory.
1525 * @param name File to find, relative to PIDDIR.
1527 * @retval Pointer to a talloc'ed string containing the full path.
1530 char *pid_path(const char *name)
1532 return xx_path(name, lp_piddir());
1536 * @brief Returns an absolute path to a file in the Samba state directory.
1538 * @param name File to find, relative to STATEDIR.
1540 * @retval Pointer to a talloc'ed string containing the full path.
1543 char *state_path(const char *name)
1545 return xx_path(name, lp_statedir());
1549 * @brief Returns an absolute path to a file in the Samba cache directory.
1551 * @param name File to find, relative to CACHEDIR.
1553 * @retval Pointer to a talloc'ed string containing the full path.
1556 char *cache_path(const char *name)
1558 return xx_path(name, lp_cachedir());
1561 /*******************************************************************
1562 Given a filename - get its directory name
1563 ********************************************************************/
1565 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1566 const char **name)
1568 char *p;
1569 ptrdiff_t len;
1571 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1573 if (p == NULL) {
1574 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1575 return False;
1577 if (name) {
1578 *name = dir;
1580 return True;
1583 len = p-dir;
1585 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1586 return False;
1588 (*parent)[len] = '\0';
1590 if (name) {
1591 *name = p+1;
1593 return True;
1596 /*******************************************************************
1597 Determine if a pattern contains any Microsoft wildcard characters.
1598 *******************************************************************/
1600 bool ms_has_wild(const char *s)
1602 char c;
1604 if (lp_posix_pathnames()) {
1605 /* With posix pathnames no characters are wild. */
1606 return False;
1609 while ((c = *s++)) {
1610 switch (c) {
1611 case '*':
1612 case '?':
1613 case '<':
1614 case '>':
1615 case '"':
1616 return True;
1619 return False;
1622 bool ms_has_wild_w(const smb_ucs2_t *s)
1624 smb_ucs2_t c;
1625 if (!s) return False;
1626 while ((c = *s++)) {
1627 switch (c) {
1628 case UCS2_CHAR('*'):
1629 case UCS2_CHAR('?'):
1630 case UCS2_CHAR('<'):
1631 case UCS2_CHAR('>'):
1632 case UCS2_CHAR('"'):
1633 return True;
1636 return False;
1639 /*******************************************************************
1640 A wrapper that handles case sensitivity and the special handling
1641 of the ".." name.
1642 *******************************************************************/
1644 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1646 if (ISDOTDOT(string))
1647 string = ".";
1648 if (ISDOT(pattern))
1649 return False;
1651 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1654 /*******************************************************************
1655 A wrapper that handles case sensitivity and the special handling
1656 of the ".." name. Varient that is only called by old search code which requires
1657 pattern translation.
1658 *******************************************************************/
1660 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1662 if (ISDOTDOT(string))
1663 string = ".";
1664 if (ISDOT(pattern))
1665 return False;
1667 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1670 /*******************************************************************
1671 A wrapper that handles a list of patters and calls mask_match()
1672 on each. Returns True if any of the patterns match.
1673 *******************************************************************/
1675 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1677 while (listLen-- > 0) {
1678 if (mask_match(string, *list++, is_case_sensitive))
1679 return True;
1681 return False;
1684 /*********************************************************
1685 Recursive routine that is called by unix_wild_match.
1686 *********************************************************/
1688 static bool unix_do_match(const char *regexp, const char *str)
1690 const char *p;
1692 for( p = regexp; *p && *str; ) {
1694 switch(*p) {
1695 case '?':
1696 str++;
1697 p++;
1698 break;
1700 case '*':
1703 * Look for a character matching
1704 * the one after the '*'.
1706 p++;
1707 if(!*p)
1708 return true; /* Automatic match */
1709 while(*str) {
1711 while(*str && (*p != *str))
1712 str++;
1715 * Patch from weidel@multichart.de. In the case of the regexp
1716 * '*XX*' we want to ensure there are at least 2 'X' characters
1717 * in the string after the '*' for a match to be made.
1721 int matchcount=0;
1724 * Eat all the characters that match, but count how many there were.
1727 while(*str && (*p == *str)) {
1728 str++;
1729 matchcount++;
1733 * Now check that if the regexp had n identical characters that
1734 * matchcount had at least that many matches.
1737 while ( *(p+1) && (*(p+1) == *p)) {
1738 p++;
1739 matchcount--;
1742 if ( matchcount <= 0 )
1743 return false;
1746 str--; /* We've eaten the match char after the '*' */
1748 if(unix_do_match(p, str))
1749 return true;
1751 if(!*str)
1752 return false;
1753 else
1754 str++;
1756 return false;
1758 default:
1759 if(*str != *p)
1760 return false;
1761 str++;
1762 p++;
1763 break;
1767 if(!*p && !*str)
1768 return true;
1770 if (!*p && str[0] == '.' && str[1] == 0)
1771 return true;
1773 if (!*str && *p == '?') {
1774 while (*p == '?')
1775 p++;
1776 return(!*p);
1779 if(!*str && (*p == '*' && p[1] == '\0'))
1780 return true;
1782 return false;
1785 /*******************************************************************
1786 Simple case insensitive interface to a UNIX wildcard matcher.
1787 Returns True if match, False if not.
1788 *******************************************************************/
1790 bool unix_wild_match(const char *pattern, const char *string)
1792 TALLOC_CTX *ctx = talloc_stackframe();
1793 char *p2;
1794 char *s2;
1795 char *p;
1796 bool ret = false;
1798 p2 = talloc_strdup(ctx,pattern);
1799 s2 = talloc_strdup(ctx,string);
1800 if (!p2 || !s2) {
1801 TALLOC_FREE(ctx);
1802 return false;
1804 strlower_m(p2);
1805 strlower_m(s2);
1807 /* Remove any *? and ** from the pattern as they are meaningless */
1808 for(p = p2; *p; p++) {
1809 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1810 memmove(&p[1], &p[2], strlen(&p[2])+1);
1814 if (strequal(p2,"*")) {
1815 TALLOC_FREE(ctx);
1816 return true;
1819 ret = unix_do_match(p2, s2);
1820 TALLOC_FREE(ctx);
1821 return ret;
1824 /**********************************************************************
1825 Converts a name to a fully qualified domain name.
1826 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1827 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1828 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1829 ***********************************************************************/
1831 bool name_to_fqdn(fstring fqdn, const char *name)
1833 char *full = NULL;
1834 struct hostent *hp = gethostbyname(name);
1836 if (!hp || !hp->h_name || !*hp->h_name) {
1837 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1838 fstrcpy(fqdn, name);
1839 return false;
1842 /* Find out if the fqdn is returned as an alias
1843 * to cope with /etc/hosts files where the first
1844 * name is not the fqdn but the short name */
1845 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1846 int i;
1847 for (i = 0; hp->h_aliases[i]; i++) {
1848 if (strchr_m(hp->h_aliases[i], '.')) {
1849 full = hp->h_aliases[i];
1850 break;
1854 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1855 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1856 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1857 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1858 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1859 full = hp->h_name;
1861 if (!full) {
1862 full = hp->h_name;
1865 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1866 fstrcpy(fqdn, full);
1867 return true;
1870 /**********************************************************************
1871 Append a DATA_BLOB to a talloc'ed object
1872 ***********************************************************************/
1874 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1876 size_t old_size = 0;
1877 char *result;
1879 if (blob.length == 0) {
1880 return buf;
1883 if (buf != NULL) {
1884 old_size = talloc_get_size(buf);
1887 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1888 if (result == NULL) {
1889 return NULL;
1892 memcpy(result + old_size, blob.data, blob.length);
1893 return result;
1896 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1898 switch (share_access & ~FILE_SHARE_DELETE) {
1899 case FILE_SHARE_NONE:
1900 return DENY_ALL;
1901 case FILE_SHARE_READ:
1902 return DENY_WRITE;
1903 case FILE_SHARE_WRITE:
1904 return DENY_READ;
1905 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1906 return DENY_NONE;
1908 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1909 return DENY_DOS;
1910 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1911 return DENY_FCB;
1914 return (uint32)-1;
1917 pid_t procid_to_pid(const struct server_id *proc)
1919 return proc->pid;
1922 static uint32 my_vnn = NONCLUSTER_VNN;
1924 void set_my_vnn(uint32 vnn)
1926 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1927 my_vnn = vnn;
1930 uint32 get_my_vnn(void)
1932 return my_vnn;
1935 static uint64_t my_unique_id = 0;
1937 void set_my_unique_id(uint64_t unique_id)
1939 my_unique_id = unique_id;
1942 struct server_id pid_to_procid(pid_t pid)
1944 struct server_id result;
1945 result.pid = pid;
1946 result.task_id = 0;
1947 result.unique_id = my_unique_id;
1948 result.vnn = my_vnn;
1949 return result;
1952 struct server_id procid_self(void)
1954 return pid_to_procid(sys_getpid());
1957 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1959 if (p1->pid != p2->pid)
1960 return False;
1961 if (p1->task_id != p2->task_id)
1962 return False;
1963 if (p1->vnn != p2->vnn)
1964 return False;
1965 return True;
1968 bool cluster_id_equal(const struct server_id *id1,
1969 const struct server_id *id2)
1971 return procid_equal(id1, id2);
1974 bool procid_is_me(const struct server_id *pid)
1976 if (pid->pid != sys_getpid())
1977 return False;
1978 if (pid->task_id != 0)
1979 return False;
1980 if (pid->vnn != my_vnn)
1981 return False;
1982 return True;
1985 struct server_id interpret_pid(const char *pid_string)
1987 struct server_id result;
1988 unsigned long long pid;
1989 unsigned int vnn, task_id = 0;
1991 ZERO_STRUCT(result);
1993 /* We accept various forms with 1, 2 or 3 component forms
1994 * because the server_id_str() can print different forms, and
1995 * we want backwards compatibility for scripts that may call
1996 * smbclient. */
1997 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
1998 result.vnn = vnn;
1999 result.pid = pid;
2000 result.task_id = task_id;
2001 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2002 result.vnn = vnn;
2003 result.pid = pid;
2004 result.task_id = 0;
2005 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2006 result.vnn = get_my_vnn();
2007 result.pid = pid;
2008 result.task_id = task_id;
2009 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2010 result.vnn = get_my_vnn();
2011 result.pid = pid;
2012 } else {
2013 result.vnn = NONCLUSTER_VNN;
2014 result.pid = (uint64_t)-1;
2016 return result;
2019 char *procid_str_static(const struct server_id *pid)
2021 return server_id_str(talloc_tos(), pid);
2024 bool procid_valid(const struct server_id *pid)
2026 return (pid->pid != (uint64_t)-1);
2029 bool procid_is_local(const struct server_id *pid)
2031 return pid->vnn == my_vnn;
2034 /****************************************************************
2035 Check if offset/length fit into bufsize. Should probably be
2036 merged with is_offset_safe, but this would require a rewrite
2037 of lanman.c. Later :-)
2038 ****************************************************************/
2040 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2042 if ((offset + length < offset) || (offset + length < length)) {
2043 /* wrap */
2044 return true;
2046 if ((offset > bufsize) || (offset + length > bufsize)) {
2047 /* overflow */
2048 return true;
2050 return false;
2053 /****************************************************************
2054 Check if an offset into a buffer is safe.
2055 If this returns True it's safe to indirect into the byte at
2056 pointer ptr+off.
2057 ****************************************************************/
2059 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2061 const char *end_base = buf_base + buf_len;
2062 char *end_ptr = ptr + off;
2064 if (!buf_base || !ptr) {
2065 return False;
2068 if (end_base < buf_base || end_ptr < ptr) {
2069 return False; /* wrap. */
2072 if (end_ptr < end_base) {
2073 return True;
2075 return False;
2078 /****************************************************************
2079 Return a safe pointer into a buffer, or NULL.
2080 ****************************************************************/
2082 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2084 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2085 ptr + off : NULL;
2088 /****************************************************************
2089 Return a safe pointer into a string within a buffer, or NULL.
2090 ****************************************************************/
2092 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2094 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2095 return NULL;
2097 /* Check if a valid string exists at this offset. */
2098 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2099 return NULL;
2101 return ptr + off;
2104 /****************************************************************
2105 Return an SVAL at a pointer, or failval if beyond the end.
2106 ****************************************************************/
2108 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2111 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2112 * NOT ptr[2].
2114 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2115 return failval;
2117 return SVAL(ptr,off);
2120 /****************************************************************
2121 Return an IVAL at a pointer, or failval if beyond the end.
2122 ****************************************************************/
2124 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2127 * Note we use off+3 here, not off+4 as IVAL accesses
2128 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2130 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2131 return failval;
2133 return IVAL(ptr,off);
2136 /****************************************************************
2137 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2138 call (they take care of winbind separator and other winbind specific settings).
2139 ****************************************************************/
2141 void split_domain_user(TALLOC_CTX *mem_ctx,
2142 const char *full_name,
2143 char **domain,
2144 char **user)
2146 const char *p = NULL;
2148 p = strchr_m(full_name, '\\');
2150 if (p != NULL) {
2151 *domain = talloc_strndup(mem_ctx, full_name,
2152 PTR_DIFF(p, full_name));
2153 *user = talloc_strdup(mem_ctx, p+1);
2154 } else {
2155 *domain = talloc_strdup(mem_ctx, "");
2156 *user = talloc_strdup(mem_ctx, full_name);
2160 /****************************************************************
2161 strip off leading '\\' from a hostname
2162 ****************************************************************/
2164 const char *strip_hostname(const char *s)
2166 if (!s) {
2167 return NULL;
2170 if (strlen_m(s) < 3) {
2171 return s;
2174 if (s[0] == '\\') s++;
2175 if (s[0] == '\\') s++;
2177 return s;
2180 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2181 struct tevent_context *ev,
2182 NTSTATUS *status)
2184 bool ret = tevent_req_poll(req, ev);
2185 if (!ret) {
2186 *status = map_nt_error_from_unix(errno);
2188 return ret;
2191 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2193 if (!NT_STATUS_IS_OK(err1)) {
2194 *result = err1;
2195 return true;
2197 if (!NT_STATUS_IS_OK(err2)) {
2198 *result = err2;
2199 return true;
2201 return false;
2204 int timeval_to_msec(struct timeval t)
2206 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2209 /*******************************************************************
2210 Check a given DOS pathname is valid for a share.
2211 ********************************************************************/
2213 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2215 char *ptr = NULL;
2217 if (!dos_pathname) {
2218 return NULL;
2221 ptr = talloc_strdup(ctx, dos_pathname);
2222 if (!ptr) {
2223 return NULL;
2225 /* Convert any '\' paths to '/' */
2226 unix_format(ptr);
2227 ptr = unix_clean_name(ctx, ptr);
2228 if (!ptr) {
2229 return NULL;
2232 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2233 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2234 ptr += 2;
2236 /* Only absolute paths allowed. */
2237 if (*ptr != '/')
2238 return NULL;
2240 return ptr;
2243 /*******************************************************************
2244 Return True if the filename is one of the special executable types.
2245 ********************************************************************/
2247 bool is_executable(const char *fname)
2249 if ((fname = strrchr_m(fname,'.'))) {
2250 if (strequal(fname,".com") ||
2251 strequal(fname,".dll") ||
2252 strequal(fname,".exe") ||
2253 strequal(fname,".sym")) {
2254 return True;
2257 return False;
2260 /****************************************************************************
2261 Open a file with a share mode - old openX method - map into NTCreate.
2262 ****************************************************************************/
2264 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2265 int deny_mode, int open_func,
2266 uint32 *paccess_mask,
2267 uint32 *pshare_mode,
2268 uint32 *pcreate_disposition,
2269 uint32 *pcreate_options,
2270 uint32_t *pprivate_flags)
2272 uint32 access_mask;
2273 uint32 share_mode;
2274 uint32 create_disposition;
2275 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2276 uint32_t private_flags = 0;
2278 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2279 "open_func = 0x%x\n",
2280 smb_base_fname, (unsigned int)deny_mode,
2281 (unsigned int)open_func ));
2283 /* Create the NT compatible access_mask. */
2284 switch (GET_OPENX_MODE(deny_mode)) {
2285 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2286 case DOS_OPEN_RDONLY:
2287 access_mask = FILE_GENERIC_READ;
2288 break;
2289 case DOS_OPEN_WRONLY:
2290 access_mask = FILE_GENERIC_WRITE;
2291 break;
2292 case DOS_OPEN_RDWR:
2293 case DOS_OPEN_FCB:
2294 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2295 break;
2296 default:
2297 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2298 (unsigned int)GET_OPENX_MODE(deny_mode)));
2299 return False;
2302 /* Create the NT compatible create_disposition. */
2303 switch (open_func) {
2304 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2305 create_disposition = FILE_CREATE;
2306 break;
2308 case OPENX_FILE_EXISTS_OPEN:
2309 create_disposition = FILE_OPEN;
2310 break;
2312 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2313 create_disposition = FILE_OPEN_IF;
2314 break;
2316 case OPENX_FILE_EXISTS_TRUNCATE:
2317 create_disposition = FILE_OVERWRITE;
2318 break;
2320 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2321 create_disposition = FILE_OVERWRITE_IF;
2322 break;
2324 default:
2325 /* From samba4 - to be confirmed. */
2326 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2327 create_disposition = FILE_CREATE;
2328 break;
2330 DEBUG(10,("map_open_params_to_ntcreate: bad "
2331 "open_func 0x%x\n", (unsigned int)open_func));
2332 return False;
2335 /* Create the NT compatible share modes. */
2336 switch (GET_DENY_MODE(deny_mode)) {
2337 case DENY_ALL:
2338 share_mode = FILE_SHARE_NONE;
2339 break;
2341 case DENY_WRITE:
2342 share_mode = FILE_SHARE_READ;
2343 break;
2345 case DENY_READ:
2346 share_mode = FILE_SHARE_WRITE;
2347 break;
2349 case DENY_NONE:
2350 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2351 break;
2353 case DENY_DOS:
2354 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2355 if (is_executable(smb_base_fname)) {
2356 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2357 } else {
2358 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2359 share_mode = FILE_SHARE_READ;
2360 } else {
2361 share_mode = FILE_SHARE_NONE;
2364 break;
2366 case DENY_FCB:
2367 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2368 share_mode = FILE_SHARE_NONE;
2369 break;
2371 default:
2372 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2373 (unsigned int)GET_DENY_MODE(deny_mode) ));
2374 return False;
2377 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2378 "share_mode = 0x%x, create_disposition = 0x%x, "
2379 "create_options = 0x%x private_flags = 0x%x\n",
2380 smb_base_fname,
2381 (unsigned int)access_mask,
2382 (unsigned int)share_mode,
2383 (unsigned int)create_disposition,
2384 (unsigned int)create_options,
2385 (unsigned int)private_flags));
2387 if (paccess_mask) {
2388 *paccess_mask = access_mask;
2390 if (pshare_mode) {
2391 *pshare_mode = share_mode;
2393 if (pcreate_disposition) {
2394 *pcreate_disposition = create_disposition;
2396 if (pcreate_options) {
2397 *pcreate_options = create_options;
2399 if (pprivate_flags) {
2400 *pprivate_flags = private_flags;
2403 return True;