Tiny simplification to dom_sid_string_buf
[Samba.git] / source3 / lib / util.c
blob173e9067cc24da3ea2f3d2d6e79666e8b662503b
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"
32 /* Max allowable allococation - 256mb - 0x10000000 */
33 #define MAX_ALLOC_SIZE (1024*1024*256)
35 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
36 #ifdef WITH_NISPLUS_HOME
37 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
39 * The following lines are needed due to buggy include files
40 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
41 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
42 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
43 * an enum in /usr/include/rpcsvc/nis.h.
46 #if defined(GROUP)
47 #undef GROUP
48 #endif
50 #if defined(GROUP_OBJ)
51 #undef GROUP_OBJ
52 #endif
54 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
56 #include <rpcsvc/nis.h>
58 #endif /* WITH_NISPLUS_HOME */
59 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
61 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
63 enum protocol_types get_Protocol(void)
65 return Protocol;
68 void set_Protocol(enum protocol_types p)
70 Protocol = p;
73 static enum remote_arch_types ra_type = RA_UNKNOWN;
75 void gfree_all( void )
77 gfree_names();
78 gfree_loadparm();
79 gfree_charcnv();
80 gfree_interfaces();
81 gfree_debugsyms();
84 /*******************************************************************
85 Check if a file exists - call vfs_file_exist for samba files.
86 ********************************************************************/
88 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
89 bool fake_dir_create_times)
91 SMB_STRUCT_STAT st;
92 if (!sbuf)
93 sbuf = &st;
95 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
96 return(False);
98 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
101 /*******************************************************************
102 Check if a unix domain socket exists - call vfs_file_exist for samba files.
103 ********************************************************************/
105 bool socket_exist(const char *fname)
107 SMB_STRUCT_STAT st;
108 if (sys_stat(fname, &st, false) != 0)
109 return(False);
111 return S_ISSOCK(st.st_ex_mode);
114 /*******************************************************************
115 Returns the size in bytes of the named given the stat struct.
116 ********************************************************************/
118 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
120 return sbuf->st_ex_size;
123 /*******************************************************************
124 Returns the size in bytes of the named file.
125 ********************************************************************/
127 SMB_OFF_T get_file_size(char *file_name)
129 SMB_STRUCT_STAT buf;
130 buf.st_ex_size = 0;
131 if (sys_stat(file_name, &buf, false) != 0)
132 return (SMB_OFF_T)-1;
133 return get_file_size_stat(&buf);
136 /*******************************************************************
137 Show a smb message structure.
138 ********************************************************************/
140 void show_msg(const char *buf)
142 int i;
143 int bcc=0;
145 if (!DEBUGLVL(5))
146 return;
148 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
149 smb_len(buf),
150 (int)CVAL(buf,smb_com),
151 (int)CVAL(buf,smb_rcls),
152 (int)CVAL(buf,smb_reh),
153 (int)SVAL(buf,smb_err),
154 (int)CVAL(buf,smb_flg),
155 (int)SVAL(buf,smb_flg2)));
156 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
157 (int)SVAL(buf,smb_tid),
158 (int)SVAL(buf,smb_pid),
159 (int)SVAL(buf,smb_uid),
160 (int)SVAL(buf,smb_mid)));
161 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
163 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
164 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
165 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
167 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
169 DEBUGADD(5,("smb_bcc=%d\n",bcc));
171 if (DEBUGLEVEL < 10)
172 return;
174 if (DEBUGLEVEL < 50)
175 bcc = MIN(bcc, 512);
177 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
180 /*******************************************************************
181 Set the length and marker of an encrypted smb packet.
182 ********************************************************************/
184 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
186 _smb_setlen(buf,len);
188 SCVAL(buf,4,0xFF);
189 SCVAL(buf,5,'E');
190 SSVAL(buf,6,enc_ctx_num);
193 /*******************************************************************
194 Set the length and marker of an smb packet.
195 ********************************************************************/
197 void smb_setlen(char *buf,int len)
199 _smb_setlen(buf,len);
201 SCVAL(buf,4,0xFF);
202 SCVAL(buf,5,'S');
203 SCVAL(buf,6,'M');
204 SCVAL(buf,7,'B');
207 /*******************************************************************
208 Setup only the byte count for a smb message.
209 ********************************************************************/
211 int set_message_bcc(char *buf,int num_bytes)
213 int num_words = CVAL(buf,smb_wct);
214 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
215 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
216 return (smb_size + num_words*2 + num_bytes);
219 /*******************************************************************
220 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
221 Return the bytes added
222 ********************************************************************/
224 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
226 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
227 uint8 *tmp;
229 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
230 DEBUG(0, ("talloc failed\n"));
231 return -1;
233 *outbuf = tmp;
235 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
236 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
237 return blob.length;
240 /*******************************************************************
241 Reduce a file name, removing .. elements.
242 ********************************************************************/
244 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
246 char *p = NULL;
247 char *str = NULL;
249 DEBUG(3,("dos_clean_name [%s]\n",s));
251 /* remove any double slashes */
252 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
253 if (!str) {
254 return NULL;
257 /* Remove leading .\\ characters */
258 if(strncmp(str, ".\\", 2) == 0) {
259 trim_string(str, ".\\", NULL);
260 if(*str == 0) {
261 str = talloc_strdup(ctx, ".\\");
262 if (!str) {
263 return NULL;
268 while ((p = strstr_m(str,"\\..\\")) != NULL) {
269 char *s1;
271 *p = 0;
272 s1 = p+3;
274 if ((p=strrchr_m(str,'\\')) != NULL) {
275 *p = 0;
276 } else {
277 *str = 0;
279 str = talloc_asprintf(ctx,
280 "%s%s",
281 str,
282 s1);
283 if (!str) {
284 return NULL;
288 trim_string(str,NULL,"\\..");
289 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
292 /*******************************************************************
293 Reduce a file name, removing .. elements.
294 ********************************************************************/
296 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
298 char *p = NULL;
299 char *str = NULL;
301 DEBUG(3,("unix_clean_name [%s]\n",s));
303 /* remove any double slashes */
304 str = talloc_all_string_sub(ctx, s, "//","/");
305 if (!str) {
306 return NULL;
309 /* Remove leading ./ characters */
310 if(strncmp(str, "./", 2) == 0) {
311 trim_string(str, "./", NULL);
312 if(*str == 0) {
313 str = talloc_strdup(ctx, "./");
314 if (!str) {
315 return NULL;
320 while ((p = strstr_m(str,"/../")) != NULL) {
321 char *s1;
323 *p = 0;
324 s1 = p+3;
326 if ((p=strrchr_m(str,'/')) != NULL) {
327 *p = 0;
328 } else {
329 *str = 0;
331 str = talloc_asprintf(ctx,
332 "%s%s",
333 str,
334 s1);
335 if (!str) {
336 return NULL;
340 trim_string(str,NULL,"/..");
341 return talloc_all_string_sub(ctx, str, "/./", "/");
344 char *clean_name(TALLOC_CTX *ctx, const char *s)
346 char *str = dos_clean_name(ctx, s);
347 if (!str) {
348 return NULL;
350 return unix_clean_name(ctx, str);
353 /*******************************************************************
354 Write data into an fd at a given offset. Ignore seek errors.
355 ********************************************************************/
357 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
359 size_t total=0;
360 ssize_t ret;
362 if (pos == (SMB_OFF_T)-1) {
363 return write_data(fd, buffer, N);
365 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
366 while (total < N) {
367 ret = sys_pwrite(fd,buffer + total,N - total, pos);
368 if (ret == -1 && errno == ESPIPE) {
369 return write_data(fd, buffer + total,N - total);
371 if (ret == -1) {
372 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
373 return -1;
375 if (ret == 0) {
376 return total;
378 total += ret;
379 pos += ret;
381 return (ssize_t)total;
382 #else
383 /* Use lseek and write_data. */
384 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
385 if (errno != ESPIPE) {
386 return -1;
389 return write_data(fd, buffer, N);
390 #endif
394 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
395 struct event_context *ev_ctx,
396 struct server_id id,
397 bool parent_longlived)
399 NTSTATUS status = NT_STATUS_OK;
401 /* Reset the state of the random
402 * number generation system, so
403 * children do not get the same random
404 * numbers as each other */
405 set_need_random_reseed();
407 /* tdb needs special fork handling */
408 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
409 DEBUG(0,("tdb_reopen_all failed.\n"));
410 status = NT_STATUS_OPEN_FAILED;
411 goto done;
414 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
415 smb_panic(__location__ ": Failed to re-initialise event context");
418 if (msg_ctx) {
420 * For clustering, we need to re-init our ctdbd connection after the
421 * fork
423 status = messaging_reinit(msg_ctx, id);
424 if (!NT_STATUS_IS_OK(status)) {
425 DEBUG(0,("messaging_reinit() failed: %s\n",
426 nt_errstr(status)));
429 done:
430 return status;
433 /****************************************************************************
434 (Hopefully) efficient array append.
435 ****************************************************************************/
437 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
438 void *element, void *_array, uint32 *num_elements,
439 ssize_t *array_size)
441 void **array = (void **)_array;
443 if (*array_size < 0) {
444 return;
447 if (*array == NULL) {
448 if (*array_size == 0) {
449 *array_size = 128;
452 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
453 goto error;
456 *array = TALLOC(mem_ctx, element_size * (*array_size));
457 if (*array == NULL) {
458 goto error;
462 if (*num_elements == *array_size) {
463 *array_size *= 2;
465 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
466 goto error;
469 *array = TALLOC_REALLOC(mem_ctx, *array,
470 element_size * (*array_size));
472 if (*array == NULL) {
473 goto error;
477 memcpy((char *)(*array) + element_size*(*num_elements),
478 element, element_size);
479 *num_elements += 1;
481 return;
483 error:
484 *num_elements = 0;
485 *array_size = -1;
488 /****************************************************************************
489 Get my own domain name, or "" if we have none.
490 ****************************************************************************/
492 char *get_mydnsdomname(TALLOC_CTX *ctx)
494 const char *domname;
495 char *p;
497 domname = get_mydnsfullname();
498 if (!domname) {
499 return NULL;
502 p = strchr_m(domname, '.');
503 if (p) {
504 p++;
505 return talloc_strdup(ctx, p);
506 } else {
507 return talloc_strdup(ctx, "");
511 /****************************************************************************
512 Interpret a protocol description string, with a default.
513 ****************************************************************************/
515 int interpret_protocol(const char *str,int def)
517 if (strequal(str,"NT1"))
518 return(PROTOCOL_NT1);
519 if (strequal(str,"LANMAN2"))
520 return(PROTOCOL_LANMAN2);
521 if (strequal(str,"LANMAN1"))
522 return(PROTOCOL_LANMAN1);
523 if (strequal(str,"CORE"))
524 return(PROTOCOL_CORE);
525 if (strequal(str,"COREPLUS"))
526 return(PROTOCOL_COREPLUS);
527 if (strequal(str,"CORE+"))
528 return(PROTOCOL_COREPLUS);
530 DEBUG(0,("Unrecognised protocol level %s\n",str));
532 return(def);
536 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
537 /******************************************************************
538 Remove any mount options such as -rsize=2048,wsize=2048 etc.
539 Based on a fix from <Thomas.Hepper@icem.de>.
540 Returns a malloc'ed string.
541 *******************************************************************/
543 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
545 if (*str == '-') {
546 const char *p = str;
547 while(*p && !isspace(*p))
548 p++;
549 while(*p && isspace(*p))
550 p++;
551 if(*p) {
552 return talloc_strdup(ctx, p);
555 return NULL;
558 /*******************************************************************
559 Patch from jkf@soton.ac.uk
560 Split Luke's automount_server into YP lookup and string splitter
561 so can easily implement automount_path().
562 Returns a malloc'ed string.
563 *******************************************************************/
565 #ifdef WITH_NISPLUS_HOME
566 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
568 char *value = NULL;
570 char *nis_map = (char *)lp_nis_home_map_name();
572 char buffer[NIS_MAXATTRVAL + 1];
573 nis_result *result;
574 nis_object *object;
575 entry_obj *entry;
577 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
578 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
580 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
581 if (result->status != NIS_SUCCESS) {
582 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
583 } else {
584 object = result->objects.objects_val;
585 if (object->zo_data.zo_type == ENTRY_OBJ) {
586 entry = &object->zo_data.objdata_u.en_data;
587 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
588 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
590 value = talloc_strdup(ctx,
591 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
592 if (!value) {
593 nis_freeresult(result);
594 return NULL;
596 value = talloc_string_sub(ctx,
597 value,
598 "&",
599 user_name);
603 nis_freeresult(result);
605 if (value) {
606 value = strip_mount_options(ctx, value);
607 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
608 user_name, value));
610 return value;
612 #else /* WITH_NISPLUS_HOME */
614 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
616 char *value = NULL;
618 int nis_error; /* returned by yp all functions */
619 char *nis_result; /* yp_match inits this */
620 int nis_result_len; /* and set this */
621 char *nis_domain; /* yp_get_default_domain inits this */
622 char *nis_map = (char *)lp_nis_home_map_name();
624 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
625 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
626 return NULL;
629 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
631 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
632 strlen(user_name), &nis_result,
633 &nis_result_len)) == 0) {
634 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
635 nis_result[nis_result_len] = '\0';
637 value = talloc_strdup(ctx, nis_result);
638 if (!value) {
639 return NULL;
641 value = strip_mount_options(ctx, value);
642 } else if(nis_error == YPERR_KEY) {
643 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
644 user_name, nis_map));
645 DEBUG(3, ("using defaults for server and home directory\n"));
646 } else {
647 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
648 yperr_string(nis_error), user_name, nis_map));
651 if (value) {
652 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
654 return value;
656 #endif /* WITH_NISPLUS_HOME */
657 #endif
659 /****************************************************************************
660 Check if a process exists. Does this work on all unixes?
661 ****************************************************************************/
663 bool process_exists(const struct server_id pid)
665 if (procid_is_me(&pid)) {
666 return True;
669 if (procid_is_local(&pid)) {
670 return (kill(pid.pid,0) == 0 || errno != ESRCH);
673 #ifdef CLUSTER_SUPPORT
674 return ctdbd_process_exists(messaging_ctdbd_connection(),
675 pid.vnn, pid.pid);
676 #else
677 return False;
678 #endif
681 /*******************************************************************
682 Convert a uid into a user name.
683 ********************************************************************/
685 const char *uidtoname(uid_t uid)
687 TALLOC_CTX *ctx = talloc_tos();
688 char *name = NULL;
689 struct passwd *pass = NULL;
691 pass = getpwuid_alloc(ctx,uid);
692 if (pass) {
693 name = talloc_strdup(ctx,pass->pw_name);
694 TALLOC_FREE(pass);
695 } else {
696 name = talloc_asprintf(ctx,
697 "%ld",
698 (long int)uid);
700 return name;
703 /*******************************************************************
704 Convert a gid into a group name.
705 ********************************************************************/
707 char *gidtoname(gid_t gid)
709 struct group *grp;
711 grp = getgrgid(gid);
712 if (grp) {
713 return talloc_strdup(talloc_tos(), grp->gr_name);
715 else {
716 return talloc_asprintf(talloc_tos(),
717 "%d",
718 (int)gid);
722 /*******************************************************************
723 Convert a user name into a uid.
724 ********************************************************************/
726 uid_t nametouid(const char *name)
728 struct passwd *pass;
729 char *p;
730 uid_t u;
732 pass = Get_Pwnam_alloc(talloc_tos(), name);
733 if (pass) {
734 u = pass->pw_uid;
735 TALLOC_FREE(pass);
736 return u;
739 u = (uid_t)strtol(name, &p, 0);
740 if ((p != name) && (*p == '\0'))
741 return u;
743 return (uid_t)-1;
746 /*******************************************************************
747 Convert a name to a gid_t if possible. Return -1 if not a group.
748 ********************************************************************/
750 gid_t nametogid(const char *name)
752 struct group *grp;
753 char *p;
754 gid_t g;
756 g = (gid_t)strtol(name, &p, 0);
757 if ((p != name) && (*p == '\0'))
758 return g;
760 grp = sys_getgrnam(name);
761 if (grp)
762 return(grp->gr_gid);
763 return (gid_t)-1;
766 /*******************************************************************
767 Something really nasty happened - panic !
768 ********************************************************************/
770 void smb_panic_s3(const char *why)
772 char *cmd;
773 int result;
775 DEBUG(0,("PANIC (pid %llu): %s\n",
776 (unsigned long long)sys_getpid(), why));
777 log_stack_trace();
779 cmd = lp_panic_action();
780 if (cmd && *cmd) {
781 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
782 result = system(cmd);
784 if (result == -1)
785 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
786 strerror(errno)));
787 else
788 DEBUG(0, ("smb_panic(): action returned status %d\n",
789 WEXITSTATUS(result)));
792 dump_core();
795 /*******************************************************************
796 Print a backtrace of the stack to the debug log. This function
797 DELIBERATELY LEAKS MEMORY. The expectation is that you should
798 exit shortly after calling it.
799 ********************************************************************/
801 #ifdef HAVE_LIBUNWIND_H
802 #include <libunwind.h>
803 #endif
805 #ifdef HAVE_EXECINFO_H
806 #include <execinfo.h>
807 #endif
809 #ifdef HAVE_LIBEXC_H
810 #include <libexc.h>
811 #endif
813 void log_stack_trace(void)
815 #ifdef HAVE_LIBUNWIND
816 /* Try to use libunwind before any other technique since on ia64
817 * libunwind correctly walks the stack in more circumstances than
818 * backtrace.
820 unw_cursor_t cursor;
821 unw_context_t uc;
822 unsigned i = 0;
824 char procname[256];
825 unw_word_t ip, sp, off;
827 procname[sizeof(procname) - 1] = '\0';
829 if (unw_getcontext(&uc) != 0) {
830 goto libunwind_failed;
833 if (unw_init_local(&cursor, &uc) != 0) {
834 goto libunwind_failed;
837 DEBUG(0, ("BACKTRACE:\n"));
839 do {
840 ip = sp = 0;
841 unw_get_reg(&cursor, UNW_REG_IP, &ip);
842 unw_get_reg(&cursor, UNW_REG_SP, &sp);
844 switch (unw_get_proc_name(&cursor,
845 procname, sizeof(procname) - 1, &off) ) {
846 case 0:
847 /* Name found. */
848 case -UNW_ENOMEM:
849 /* Name truncated. */
850 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
851 i, procname, (long long)off,
852 (long long)ip, (long long) sp));
853 break;
854 default:
855 /* case -UNW_ENOINFO: */
856 /* case -UNW_EUNSPEC: */
857 /* No symbol name found. */
858 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
859 i, "<unknown symbol>",
860 (long long)ip, (long long) sp));
862 ++i;
863 } while (unw_step(&cursor) > 0);
865 return;
867 libunwind_failed:
868 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
870 #elif HAVE_BACKTRACE_SYMBOLS
871 void *backtrace_stack[BACKTRACE_STACK_SIZE];
872 size_t backtrace_size;
873 char **backtrace_strings;
875 /* get the backtrace (stack frames) */
876 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
877 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
879 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
880 (unsigned long)backtrace_size));
882 if (backtrace_strings) {
883 int i;
885 for (i = 0; i < backtrace_size; i++)
886 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
888 /* Leak the backtrace_strings, rather than risk what free() might do */
891 #elif HAVE_LIBEXC
893 /* The IRIX libexc library provides an API for unwinding the stack. See
894 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
895 * since we are about to abort anyway, it hardly matters.
898 #define NAMESIZE 32 /* Arbitrary */
900 __uint64_t addrs[BACKTRACE_STACK_SIZE];
901 char * names[BACKTRACE_STACK_SIZE];
902 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
904 int i;
905 int levels;
907 ZERO_ARRAY(addrs);
908 ZERO_ARRAY(names);
909 ZERO_ARRAY(namebuf);
911 /* We need to be root so we can open our /proc entry to walk
912 * our stack. It also helps when we want to dump core.
914 become_root();
916 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
917 names[i] = namebuf + (i * NAMESIZE);
920 levels = trace_back_stack(0, addrs, names,
921 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
923 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
924 for (i = 0; i < levels; i++) {
925 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
927 #undef NAMESIZE
929 #else
930 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
931 #endif
934 /*******************************************************************
935 A readdir wrapper which just returns the file name.
936 ********************************************************************/
938 const char *readdirname(SMB_STRUCT_DIR *p)
940 SMB_STRUCT_DIRENT *ptr;
941 char *dname;
943 if (!p)
944 return(NULL);
946 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
947 if (!ptr)
948 return(NULL);
950 dname = ptr->d_name;
952 #ifdef NEXT2
953 if (telldir(p) < 0)
954 return(NULL);
955 #endif
957 #ifdef HAVE_BROKEN_READDIR_NAME
958 /* using /usr/ucb/cc is BAD */
959 dname = dname - 2;
960 #endif
962 return talloc_strdup(talloc_tos(), dname);
965 /*******************************************************************
966 Utility function used to decide if the last component
967 of a path matches a (possibly wildcarded) entry in a namelist.
968 ********************************************************************/
970 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
972 const char *last_component;
974 /* if we have no list it's obviously not in the path */
975 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
976 return False;
979 DEBUG(8, ("is_in_path: %s\n", name));
981 /* Get the last component of the unix name. */
982 last_component = strrchr_m(name, '/');
983 if (!last_component) {
984 last_component = name;
985 } else {
986 last_component++; /* Go past '/' */
989 for(; namelist->name != NULL; namelist++) {
990 if(namelist->is_wild) {
991 if (mask_match(last_component, namelist->name, case_sensitive)) {
992 DEBUG(8,("is_in_path: mask match succeeded\n"));
993 return True;
995 } else {
996 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
997 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
998 DEBUG(8,("is_in_path: match succeeded\n"));
999 return True;
1003 DEBUG(8,("is_in_path: match not found\n"));
1004 return False;
1007 /*******************************************************************
1008 Strip a '/' separated list into an array of
1009 name_compare_enties structures suitable for
1010 passing to is_in_path(). We do this for
1011 speed so we can pre-parse all the names in the list
1012 and don't do it for each call to is_in_path().
1013 We also check if the entry contains a wildcard to
1014 remove a potentially expensive call to mask_match
1015 if possible.
1016 ********************************************************************/
1018 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1020 char *name_end;
1021 char *namelist;
1022 char *nameptr;
1023 int num_entries = 0;
1024 int i;
1026 (*ppname_array) = NULL;
1028 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1029 return;
1031 namelist = talloc_strdup(talloc_tos(), namelist_in);
1032 if (namelist == NULL) {
1033 DEBUG(0,("set_namearray: talloc fail\n"));
1034 return;
1036 nameptr = namelist;
1038 /* We need to make two passes over the string. The
1039 first to count the number of elements, the second
1040 to split it.
1043 while(*nameptr) {
1044 if ( *nameptr == '/' ) {
1045 /* cope with multiple (useless) /s) */
1046 nameptr++;
1047 continue;
1049 /* anything left? */
1050 if ( *nameptr == '\0' )
1051 break;
1053 /* find the next '/' or consume remaining */
1054 name_end = strchr_m(nameptr, '/');
1055 if (name_end == NULL)
1056 name_end = (char *)nameptr + strlen(nameptr);
1058 /* next segment please */
1059 nameptr = name_end + 1;
1060 num_entries++;
1063 if(num_entries == 0) {
1064 talloc_free(namelist);
1065 return;
1068 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1069 DEBUG(0,("set_namearray: malloc fail\n"));
1070 talloc_free(namelist);
1071 return;
1074 /* Now copy out the names */
1075 nameptr = namelist;
1076 i = 0;
1077 while(*nameptr) {
1078 if ( *nameptr == '/' ) {
1079 /* cope with multiple (useless) /s) */
1080 nameptr++;
1081 continue;
1083 /* anything left? */
1084 if ( *nameptr == '\0' )
1085 break;
1087 /* find the next '/' or consume remaining */
1088 name_end = strchr_m(nameptr, '/');
1089 if (name_end)
1090 *name_end = '\0';
1091 else
1092 name_end = nameptr + strlen(nameptr);
1094 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1095 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1096 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1097 talloc_free(namelist);
1098 return;
1101 /* next segment please */
1102 nameptr = name_end + 1;
1103 i++;
1106 (*ppname_array)[i].name = NULL;
1108 talloc_free(namelist);
1109 return;
1112 #undef DBGC_CLASS
1113 #define DBGC_CLASS DBGC_LOCKING
1115 /****************************************************************************
1116 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1117 is dealt with in posix.c
1118 Returns True if we have information regarding this lock region (and returns
1119 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1120 ****************************************************************************/
1122 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1124 SMB_STRUCT_FLOCK lock;
1125 int ret;
1127 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1128 fd,(double)*poffset,(double)*pcount,*ptype));
1130 lock.l_type = *ptype;
1131 lock.l_whence = SEEK_SET;
1132 lock.l_start = *poffset;
1133 lock.l_len = *pcount;
1134 lock.l_pid = 0;
1136 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1138 if (ret == -1) {
1139 int sav = errno;
1140 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1141 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1142 errno = sav;
1143 return False;
1146 *ptype = lock.l_type;
1147 *poffset = lock.l_start;
1148 *pcount = lock.l_len;
1149 *ppid = lock.l_pid;
1151 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1152 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1153 return True;
1156 #undef DBGC_CLASS
1157 #define DBGC_CLASS DBGC_ALL
1159 /*******************************************************************
1160 Is the name specified one of my netbios names.
1161 Returns true if it is equal, false otherwise.
1162 ********************************************************************/
1164 bool is_myname(const char *s)
1166 int n;
1167 bool ret = False;
1169 for (n=0; my_netbios_names(n); n++) {
1170 if (strequal(my_netbios_names(n), s)) {
1171 ret=True;
1172 break;
1175 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1176 return(ret);
1179 /*******************************************************************
1180 Is the name specified our workgroup/domain.
1181 Returns true if it is equal, false otherwise.
1182 ********************************************************************/
1184 bool is_myworkgroup(const char *s)
1186 bool ret = False;
1188 if (strequal(s, lp_workgroup())) {
1189 ret=True;
1192 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1193 return(ret);
1196 /*******************************************************************
1197 we distinguish between 2K and XP by the "Native Lan Manager" string
1198 WinXP => "Windows 2002 5.1"
1199 WinXP 64bit => "Windows XP 5.2"
1200 Win2k => "Windows 2000 5.0"
1201 NT4 => "Windows NT 4.0"
1202 Win9x => "Windows 4.0"
1203 Windows 2003 doesn't set the native lan manager string but
1204 they do set the domain to "Windows 2003 5.2" (probably a bug).
1205 ********************************************************************/
1207 void ra_lanman_string( const char *native_lanman )
1209 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1210 set_remote_arch( RA_WINXP );
1211 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1212 set_remote_arch( RA_WINXP64 );
1213 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1214 set_remote_arch( RA_WIN2K3 );
1217 static const char *remote_arch_str;
1219 const char *get_remote_arch_str(void)
1221 if (!remote_arch_str) {
1222 return "UNKNOWN";
1224 return remote_arch_str;
1227 /*******************************************************************
1228 Set the horrid remote_arch string based on an enum.
1229 ********************************************************************/
1231 void set_remote_arch(enum remote_arch_types type)
1233 ra_type = type;
1234 switch( type ) {
1235 case RA_WFWG:
1236 remote_arch_str = "WfWg";
1237 break;
1238 case RA_OS2:
1239 remote_arch_str = "OS2";
1240 break;
1241 case RA_WIN95:
1242 remote_arch_str = "Win95";
1243 break;
1244 case RA_WINNT:
1245 remote_arch_str = "WinNT";
1246 break;
1247 case RA_WIN2K:
1248 remote_arch_str = "Win2K";
1249 break;
1250 case RA_WINXP:
1251 remote_arch_str = "WinXP";
1252 break;
1253 case RA_WINXP64:
1254 remote_arch_str = "WinXP64";
1255 break;
1256 case RA_WIN2K3:
1257 remote_arch_str = "Win2K3";
1258 break;
1259 case RA_VISTA:
1260 remote_arch_str = "Vista";
1261 break;
1262 case RA_SAMBA:
1263 remote_arch_str = "Samba";
1264 break;
1265 case RA_CIFSFS:
1266 remote_arch_str = "CIFSFS";
1267 break;
1268 case RA_OSX:
1269 remote_arch_str = "OSX";
1270 break;
1271 default:
1272 ra_type = RA_UNKNOWN;
1273 remote_arch_str = "UNKNOWN";
1274 break;
1277 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1278 remote_arch_str));
1281 /*******************************************************************
1282 Get the remote_arch type.
1283 ********************************************************************/
1285 enum remote_arch_types get_remote_arch(void)
1287 return ra_type;
1290 const char *tab_depth(int level, int depth)
1292 if( CHECK_DEBUGLVL(level) ) {
1293 dbgtext("%*s", depth*4, "");
1295 return "";
1298 /*****************************************************************************
1299 Provide a checksum on a string
1301 Input: s - the null-terminated character string for which the checksum
1302 will be calculated.
1304 Output: The checksum value calculated for s.
1305 *****************************************************************************/
1307 int str_checksum(const char *s)
1309 TDB_DATA key = string_tdb_data(s);
1310 return tdb_jenkins_hash(&key);
1313 /*****************************************************************
1314 Zero a memory area then free it. Used to catch bugs faster.
1315 *****************************************************************/
1317 void zero_free(void *p, size_t size)
1319 memset(p, 0, size);
1320 SAFE_FREE(p);
1323 /*****************************************************************
1324 Set our open file limit to a requested max and return the limit.
1325 *****************************************************************/
1327 int set_maxfiles(int requested_max)
1329 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1330 struct rlimit rlp;
1331 int saved_current_limit;
1333 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1334 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1335 strerror(errno) ));
1336 /* just guess... */
1337 return requested_max;
1341 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1342 * account for the extra fd we need
1343 * as well as the log files and standard
1344 * handles etc. Save the limit we want to set in case
1345 * we are running on an OS that doesn't support this limit (AIX)
1346 * which always returns RLIM_INFINITY for rlp.rlim_max.
1349 /* Try raising the hard (max) limit to the requested amount. */
1351 #if defined(RLIM_INFINITY)
1352 if (rlp.rlim_max != RLIM_INFINITY) {
1353 int orig_max = rlp.rlim_max;
1355 if ( rlp.rlim_max < requested_max )
1356 rlp.rlim_max = requested_max;
1358 /* This failing is not an error - many systems (Linux) don't
1359 support our default request of 10,000 open files. JRA. */
1361 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1362 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1363 (int)rlp.rlim_max, strerror(errno) ));
1365 /* Set failed - restore original value from get. */
1366 rlp.rlim_max = orig_max;
1369 #endif
1371 /* Now try setting the soft (current) limit. */
1373 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1375 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1376 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1377 (int)rlp.rlim_cur, strerror(errno) ));
1378 /* just guess... */
1379 return saved_current_limit;
1382 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1383 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1384 strerror(errno) ));
1385 /* just guess... */
1386 return saved_current_limit;
1389 #if defined(RLIM_INFINITY)
1390 if(rlp.rlim_cur == RLIM_INFINITY)
1391 return saved_current_limit;
1392 #endif
1394 if((int)rlp.rlim_cur > saved_current_limit)
1395 return saved_current_limit;
1397 return rlp.rlim_cur;
1398 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1400 * No way to know - just guess...
1402 return requested_max;
1403 #endif
1406 /*****************************************************************
1407 malloc that aborts with smb_panic on fail or zero size.
1408 *****************************************************************/
1410 void *smb_xmalloc_array(size_t size, unsigned int count)
1412 void *p;
1413 if (size == 0) {
1414 smb_panic("smb_xmalloc_array: called with zero size");
1416 if (count >= MAX_ALLOC_SIZE/size) {
1417 smb_panic("smb_xmalloc_array: alloc size too large");
1419 if ((p = SMB_MALLOC(size*count)) == NULL) {
1420 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1421 (unsigned long)size, (unsigned long)count));
1422 smb_panic("smb_xmalloc_array: malloc failed");
1424 return p;
1428 vasprintf that aborts on malloc fail
1431 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1433 int n;
1434 va_list ap2;
1436 va_copy(ap2, ap);
1438 n = vasprintf(ptr, format, ap2);
1439 va_end(ap2);
1440 if (n == -1 || ! *ptr) {
1441 smb_panic("smb_xvasprintf: out of memory");
1443 return n;
1446 /*****************************************************************
1447 Get local hostname and cache result.
1448 *****************************************************************/
1450 char *myhostname(void)
1452 static char *ret;
1453 if (ret == NULL) {
1454 ret = get_myname(NULL);
1456 return ret;
1460 * @brief Returns an absolute path to a file concatenating the provided
1461 * @a rootpath and @a basename
1463 * @param name Filename, relative to @a rootpath
1465 * @retval Pointer to a string containing the full path.
1468 static char *xx_path(const char *name, const char *rootpath)
1470 char *fname = NULL;
1472 fname = talloc_strdup(talloc_tos(), rootpath);
1473 if (!fname) {
1474 return NULL;
1476 trim_string(fname,"","/");
1478 if (!directory_exist(fname)) {
1479 if (!mkdir(fname,0755))
1480 DEBUG(1, ("Unable to create directory %s for file %s. "
1481 "Error was %s\n", fname, name, strerror(errno)));
1484 return talloc_asprintf(talloc_tos(),
1485 "%s/%s",
1486 fname,
1487 name);
1491 * @brief Returns an absolute path to a file in the Samba lock directory.
1493 * @param name File to find, relative to LOCKDIR.
1495 * @retval Pointer to a talloc'ed string containing the full path.
1498 char *lock_path(const char *name)
1500 return xx_path(name, lp_lockdir());
1504 * @brief Returns an absolute path to a file in the Samba pid directory.
1506 * @param name File to find, relative to PIDDIR.
1508 * @retval Pointer to a talloc'ed string containing the full path.
1511 char *pid_path(const char *name)
1513 return xx_path(name, lp_piddir());
1517 * @brief Returns an absolute path to a file in the Samba lib directory.
1519 * @param name File to find, relative to LIBDIR.
1521 * @retval Pointer to a string containing the full path.
1524 char *lib_path(const char *name)
1526 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
1530 * @brief Returns an absolute path to a file in the Samba modules directory.
1532 * @param name File to find, relative to MODULESDIR.
1534 * @retval Pointer to a string containing the full path.
1537 char *modules_path(const char *name)
1539 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
1543 * @brief Returns an absolute path to a file in the Samba data directory.
1545 * @param name File to find, relative to CODEPAGEDIR.
1547 * @retval Pointer to a talloc'ed string containing the full path.
1550 char *data_path(const char *name)
1552 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
1556 * @brief Returns an absolute path to a file in the Samba state directory.
1558 * @param name File to find, relative to STATEDIR.
1560 * @retval Pointer to a talloc'ed string containing the full path.
1563 char *state_path(const char *name)
1565 return xx_path(name, lp_statedir());
1569 * @brief Returns an absolute path to a file in the Samba cache directory.
1571 * @param name File to find, relative to CACHEDIR.
1573 * @retval Pointer to a talloc'ed string containing the full path.
1576 char *cache_path(const char *name)
1578 return xx_path(name, lp_cachedir());
1582 * @brief Returns the platform specific shared library extension.
1584 * @retval Pointer to a const char * containing the extension.
1587 const char *shlib_ext(void)
1589 return get_dyn_SHLIBEXT();
1592 /*******************************************************************
1593 Given a filename - get its directory name
1594 ********************************************************************/
1596 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1597 const char **name)
1599 char *p;
1600 ptrdiff_t len;
1602 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1604 if (p == NULL) {
1605 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1606 return False;
1608 if (name) {
1609 *name = dir;
1611 return True;
1614 len = p-dir;
1616 if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
1617 return False;
1619 (*parent)[len] = '\0';
1621 if (name) {
1622 *name = p+1;
1624 return True;
1627 /*******************************************************************
1628 Determine if a pattern contains any Microsoft wildcard characters.
1629 *******************************************************************/
1631 bool ms_has_wild(const char *s)
1633 char c;
1635 if (lp_posix_pathnames()) {
1636 /* With posix pathnames no characters are wild. */
1637 return False;
1640 while ((c = *s++)) {
1641 switch (c) {
1642 case '*':
1643 case '?':
1644 case '<':
1645 case '>':
1646 case '"':
1647 return True;
1650 return False;
1653 bool ms_has_wild_w(const smb_ucs2_t *s)
1655 smb_ucs2_t c;
1656 if (!s) return False;
1657 while ((c = *s++)) {
1658 switch (c) {
1659 case UCS2_CHAR('*'):
1660 case UCS2_CHAR('?'):
1661 case UCS2_CHAR('<'):
1662 case UCS2_CHAR('>'):
1663 case UCS2_CHAR('"'):
1664 return True;
1667 return False;
1670 /*******************************************************************
1671 A wrapper that handles case sensitivity and the special handling
1672 of the ".." name.
1673 *******************************************************************/
1675 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1677 if (ISDOTDOT(string))
1678 string = ".";
1679 if (ISDOT(pattern))
1680 return False;
1682 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1685 /*******************************************************************
1686 A wrapper that handles case sensitivity and the special handling
1687 of the ".." name. Varient that is only called by old search code which requires
1688 pattern translation.
1689 *******************************************************************/
1691 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1693 if (ISDOTDOT(string))
1694 string = ".";
1695 if (ISDOT(pattern))
1696 return False;
1698 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1701 /*******************************************************************
1702 A wrapper that handles a list of patters and calls mask_match()
1703 on each. Returns True if any of the patterns match.
1704 *******************************************************************/
1706 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1708 while (listLen-- > 0) {
1709 if (mask_match(string, *list++, is_case_sensitive))
1710 return True;
1712 return False;
1715 /*********************************************************
1716 Recursive routine that is called by unix_wild_match.
1717 *********************************************************/
1719 static bool unix_do_match(const char *regexp, const char *str)
1721 const char *p;
1723 for( p = regexp; *p && *str; ) {
1725 switch(*p) {
1726 case '?':
1727 str++;
1728 p++;
1729 break;
1731 case '*':
1734 * Look for a character matching
1735 * the one after the '*'.
1737 p++;
1738 if(!*p)
1739 return true; /* Automatic match */
1740 while(*str) {
1742 while(*str && (*p != *str))
1743 str++;
1746 * Patch from weidel@multichart.de. In the case of the regexp
1747 * '*XX*' we want to ensure there are at least 2 'X' characters
1748 * in the string after the '*' for a match to be made.
1752 int matchcount=0;
1755 * Eat all the characters that match, but count how many there were.
1758 while(*str && (*p == *str)) {
1759 str++;
1760 matchcount++;
1764 * Now check that if the regexp had n identical characters that
1765 * matchcount had at least that many matches.
1768 while ( *(p+1) && (*(p+1) == *p)) {
1769 p++;
1770 matchcount--;
1773 if ( matchcount <= 0 )
1774 return false;
1777 str--; /* We've eaten the match char after the '*' */
1779 if(unix_do_match(p, str))
1780 return true;
1782 if(!*str)
1783 return false;
1784 else
1785 str++;
1787 return false;
1789 default:
1790 if(*str != *p)
1791 return false;
1792 str++;
1793 p++;
1794 break;
1798 if(!*p && !*str)
1799 return true;
1801 if (!*p && str[0] == '.' && str[1] == 0)
1802 return true;
1804 if (!*str && *p == '?') {
1805 while (*p == '?')
1806 p++;
1807 return(!*p);
1810 if(!*str && (*p == '*' && p[1] == '\0'))
1811 return true;
1813 return false;
1816 /*******************************************************************
1817 Simple case insensitive interface to a UNIX wildcard matcher.
1818 Returns True if match, False if not.
1819 *******************************************************************/
1821 bool unix_wild_match(const char *pattern, const char *string)
1823 TALLOC_CTX *ctx = talloc_stackframe();
1824 char *p2;
1825 char *s2;
1826 char *p;
1827 bool ret = false;
1829 p2 = talloc_strdup(ctx,pattern);
1830 s2 = talloc_strdup(ctx,string);
1831 if (!p2 || !s2) {
1832 TALLOC_FREE(ctx);
1833 return false;
1835 strlower_m(p2);
1836 strlower_m(s2);
1838 /* Remove any *? and ** from the pattern as they are meaningless */
1839 for(p = p2; *p; p++) {
1840 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1841 memmove(&p[1], &p[2], strlen(&p[2])+1);
1845 if (strequal(p2,"*")) {
1846 TALLOC_FREE(ctx);
1847 return true;
1850 ret = unix_do_match(p2, s2);
1851 TALLOC_FREE(ctx);
1852 return ret;
1855 /**********************************************************************
1856 Converts a name to a fully qualified domain name.
1857 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1858 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1859 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1860 ***********************************************************************/
1862 bool name_to_fqdn(fstring fqdn, const char *name)
1864 char *full = NULL;
1865 struct hostent *hp = gethostbyname(name);
1867 if (!hp || !hp->h_name || !*hp->h_name) {
1868 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1869 fstrcpy(fqdn, name);
1870 return false;
1873 /* Find out if the fqdn is returned as an alias
1874 * to cope with /etc/hosts files where the first
1875 * name is not the fqdn but the short name */
1876 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1877 int i;
1878 for (i = 0; hp->h_aliases[i]; i++) {
1879 if (strchr_m(hp->h_aliases[i], '.')) {
1880 full = hp->h_aliases[i];
1881 break;
1885 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1886 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1887 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1888 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1889 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1890 full = hp->h_name;
1892 if (!full) {
1893 full = hp->h_name;
1896 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1897 fstrcpy(fqdn, full);
1898 return true;
1901 /**********************************************************************
1902 Append a DATA_BLOB to a talloc'ed object
1903 ***********************************************************************/
1905 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1907 size_t old_size = 0;
1908 char *result;
1910 if (blob.length == 0) {
1911 return buf;
1914 if (buf != NULL) {
1915 old_size = talloc_get_size(buf);
1918 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1919 if (result == NULL) {
1920 return NULL;
1923 memcpy(result + old_size, blob.data, blob.length);
1924 return result;
1927 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1929 switch (share_access & ~FILE_SHARE_DELETE) {
1930 case FILE_SHARE_NONE:
1931 return DENY_ALL;
1932 case FILE_SHARE_READ:
1933 return DENY_WRITE;
1934 case FILE_SHARE_WRITE:
1935 return DENY_READ;
1936 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1937 return DENY_NONE;
1939 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1940 return DENY_DOS;
1941 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1942 return DENY_FCB;
1945 return (uint32)-1;
1948 pid_t procid_to_pid(const struct server_id *proc)
1950 return proc->pid;
1953 static uint32 my_vnn = NONCLUSTER_VNN;
1955 void set_my_vnn(uint32 vnn)
1957 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1958 my_vnn = vnn;
1961 uint32 get_my_vnn(void)
1963 return my_vnn;
1966 static uint64_t my_unique_id = 0;
1968 void set_my_unique_id(uint64_t unique_id)
1970 my_unique_id = unique_id;
1973 struct server_id pid_to_procid(pid_t pid)
1975 struct server_id result;
1976 result.pid = pid;
1977 result.unique_id = my_unique_id;
1978 result.vnn = my_vnn;
1979 return result;
1982 struct server_id procid_self(void)
1984 return pid_to_procid(sys_getpid());
1987 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
1989 if (p1->pid != p2->pid)
1990 return False;
1991 if (p1->vnn != p2->vnn)
1992 return False;
1993 return True;
1996 bool cluster_id_equal(const struct server_id *id1,
1997 const struct server_id *id2)
1999 return procid_equal(id1, id2);
2002 bool procid_is_me(const struct server_id *pid)
2004 if (pid->pid != sys_getpid())
2005 return False;
2006 if (pid->vnn != my_vnn)
2007 return False;
2008 return True;
2011 struct server_id interpret_pid(const char *pid_string)
2013 struct server_id result;
2014 int pid;
2015 unsigned int vnn;
2016 if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
2017 result.vnn = vnn;
2018 result.pid = pid;
2020 else if (sscanf(pid_string, "%d", &pid) == 1) {
2021 result.vnn = get_my_vnn();
2022 result.pid = pid;
2024 else {
2025 result.vnn = NONCLUSTER_VNN;
2026 result.pid = -1;
2028 /* Assigning to result.pid may have overflowed
2029 Map negative pid to -1: i.e. error */
2030 if (result.pid < 0) {
2031 result.pid = -1;
2033 result.unique_id = 0;
2034 return result;
2037 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2039 if (pid->vnn == NONCLUSTER_VNN) {
2040 return talloc_asprintf(mem_ctx,
2041 "%d",
2042 (int)pid->pid);
2044 else {
2045 return talloc_asprintf(mem_ctx,
2046 "%u:%d",
2047 (unsigned)pid->vnn,
2048 (int)pid->pid);
2052 char *procid_str_static(const struct server_id *pid)
2054 return procid_str(talloc_tos(), pid);
2057 bool procid_valid(const struct server_id *pid)
2059 return (pid->pid != -1);
2062 bool procid_is_local(const struct server_id *pid)
2064 return pid->vnn == my_vnn;
2067 /****************************************************************
2068 Check if offset/length fit into bufsize. Should probably be
2069 merged with is_offset_safe, but this would require a rewrite
2070 of lanman.c. Later :-)
2071 ****************************************************************/
2073 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2075 if ((offset + length < offset) || (offset + length < length)) {
2076 /* wrap */
2077 return true;
2079 if ((offset > bufsize) || (offset + length > bufsize)) {
2080 /* overflow */
2081 return true;
2083 return false;
2086 /****************************************************************
2087 Check if an offset into a buffer is safe.
2088 If this returns True it's safe to indirect into the byte at
2089 pointer ptr+off.
2090 ****************************************************************/
2092 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2094 const char *end_base = buf_base + buf_len;
2095 char *end_ptr = ptr + off;
2097 if (!buf_base || !ptr) {
2098 return False;
2101 if (end_base < buf_base || end_ptr < ptr) {
2102 return False; /* wrap. */
2105 if (end_ptr < end_base) {
2106 return True;
2108 return False;
2111 /****************************************************************
2112 Return a safe pointer into a buffer, or NULL.
2113 ****************************************************************/
2115 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2117 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2118 ptr + off : NULL;
2121 /****************************************************************
2122 Return a safe pointer into a string within a buffer, or NULL.
2123 ****************************************************************/
2125 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2127 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2128 return NULL;
2130 /* Check if a valid string exists at this offset. */
2131 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2132 return NULL;
2134 return ptr + off;
2137 /****************************************************************
2138 Return an SVAL at a pointer, or failval if beyond the end.
2139 ****************************************************************/
2141 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2144 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2145 * NOT ptr[2].
2147 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2148 return failval;
2150 return SVAL(ptr,off);
2153 /****************************************************************
2154 Return an IVAL at a pointer, or failval if beyond the end.
2155 ****************************************************************/
2157 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2160 * Note we use off+3 here, not off+4 as IVAL accesses
2161 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2163 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2164 return failval;
2166 return IVAL(ptr,off);
2169 /****************************************************************
2170 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2171 call (they take care of winbind separator and other winbind specific settings).
2172 ****************************************************************/
2174 void split_domain_user(TALLOC_CTX *mem_ctx,
2175 const char *full_name,
2176 char **domain,
2177 char **user)
2179 const char *p = NULL;
2181 p = strchr_m(full_name, '\\');
2183 if (p != NULL) {
2184 *domain = talloc_strndup(mem_ctx, full_name,
2185 PTR_DIFF(p, full_name));
2186 *user = talloc_strdup(mem_ctx, p+1);
2187 } else {
2188 *domain = talloc_strdup(mem_ctx, "");
2189 *user = talloc_strdup(mem_ctx, full_name);
2193 #if 0
2195 Disable these now we have checked all code paths and ensured
2196 NULL returns on zero request. JRA.
2198 /****************************************************************
2199 talloc wrapper functions that guarentee a null pointer return
2200 if size == 0.
2201 ****************************************************************/
2203 #ifndef MAX_TALLOC_SIZE
2204 #define MAX_TALLOC_SIZE 0x10000000
2205 #endif
2208 * talloc and zero memory.
2209 * - returns NULL if size is zero.
2212 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2214 void *p;
2216 if (size == 0) {
2217 return NULL;
2220 p = talloc_named_const(ctx, size, name);
2222 if (p) {
2223 memset(p, '\0', size);
2226 return p;
2230 * memdup with a talloc.
2231 * - returns NULL if size is zero.
2234 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
2236 void *newp;
2238 if (size == 0) {
2239 return NULL;
2242 newp = talloc_named_const(t, size, name);
2243 if (newp) {
2244 memcpy(newp, p, size);
2247 return newp;
2251 * alloc an array, checking for integer overflow in the array size.
2252 * - returns NULL if count or el_size are zero.
2255 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2257 if (count >= MAX_TALLOC_SIZE/el_size) {
2258 return NULL;
2261 if (el_size == 0 || count == 0) {
2262 return NULL;
2265 return talloc_named_const(ctx, el_size * count, name);
2269 * alloc an zero array, checking for integer overflow in the array size
2270 * - returns NULL if count or el_size are zero.
2273 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2275 if (count >= MAX_TALLOC_SIZE/el_size) {
2276 return NULL;
2279 if (el_size == 0 || count == 0) {
2280 return NULL;
2283 return _talloc_zero(ctx, el_size * count, name);
2287 * Talloc wrapper that returns NULL if size == 0.
2289 void *talloc_zeronull(const void *context, size_t size, const char *name)
2291 if (size == 0) {
2292 return NULL;
2294 return talloc_named_const(context, size, name);
2296 #endif
2298 /****************************************************************
2299 strip off leading '\\' from a hostname
2300 ****************************************************************/
2302 const char *strip_hostname(const char *s)
2304 if (!s) {
2305 return NULL;
2308 if (strlen_m(s) < 3) {
2309 return s;
2312 if (s[0] == '\\') s++;
2313 if (s[0] == '\\') s++;
2315 return s;
2318 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2319 struct tevent_context *ev,
2320 NTSTATUS *status)
2322 bool ret = tevent_req_poll(req, ev);
2323 if (!ret) {
2324 *status = map_nt_error_from_unix(errno);
2326 return ret;
2329 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2331 if (!NT_STATUS_IS_OK(err1)) {
2332 *result = err1;
2333 return true;
2335 if (!NT_STATUS_IS_OK(err2)) {
2336 *result = err2;
2337 return true;
2339 return false;
2342 int timeval_to_msec(struct timeval t)
2344 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2347 /*******************************************************************
2348 Check a given DOS pathname is valid for a share.
2349 ********************************************************************/
2351 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2353 char *ptr = NULL;
2355 if (!dos_pathname) {
2356 return NULL;
2359 ptr = talloc_strdup(ctx, dos_pathname);
2360 if (!ptr) {
2361 return NULL;
2363 /* Convert any '\' paths to '/' */
2364 unix_format(ptr);
2365 ptr = unix_clean_name(ctx, ptr);
2366 if (!ptr) {
2367 return NULL;
2370 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2371 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2372 ptr += 2;
2374 /* Only absolute paths allowed. */
2375 if (*ptr != '/')
2376 return NULL;
2378 return ptr;