Fix smbclient/tarmode panic on connecting to Windows 2000 clients.
[Samba.git] / source3 / lib / util.c
blobb8513f6b9fa45b09e9992aceb6b16b48142967c5
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "util_tdb.h"
28 #include "ctdbd_conn.h"
29 #include "../lib/util/util_pw.h"
30 #include "messages.h"
31 #include <ccan/hash/hash.h>
32 #include "libcli/security/security.h"
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
36 #endif
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
45 * The following lines are needed due to buggy include files
46 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
47 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
48 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
49 * an enum in /usr/include/rpcsvc/nis.h.
52 #if defined(GROUP)
53 #undef GROUP
54 #endif
56 #if defined(GROUP_OBJ)
57 #undef GROUP_OBJ
58 #endif
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
62 #include <rpcsvc/nis.h>
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
69 enum protocol_types get_Protocol(void)
71 return Protocol;
74 void set_Protocol(enum protocol_types p)
76 Protocol = p;
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 void gfree_all( void )
83 gfree_names();
84 gfree_loadparm();
85 gfree_charcnv();
86 gfree_interfaces();
87 gfree_debugsyms();
90 /*******************************************************************
91 Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95 bool fake_dir_create_times)
97 SMB_STRUCT_STAT st;
98 if (!sbuf)
99 sbuf = &st;
101 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
102 return(False);
104 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
107 /*******************************************************************
108 Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
111 bool socket_exist(const char *fname)
113 SMB_STRUCT_STAT st;
114 if (sys_stat(fname, &st, false) != 0)
115 return(False);
117 return S_ISSOCK(st.st_ex_mode);
120 /*******************************************************************
121 Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
126 return sbuf->st_ex_size;
129 /****************************************************************************
130 Check two stats have identical dev and ino fields.
131 ****************************************************************************/
133 bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1,
134 const SMB_STRUCT_STAT *sbuf2)
136 if (sbuf1->st_ex_dev != sbuf2->st_ex_dev ||
137 sbuf1->st_ex_ino != sbuf2->st_ex_ino) {
138 return false;
140 return true;
143 /****************************************************************************
144 Check if a stat struct is identical for use.
145 ****************************************************************************/
147 bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
148 const SMB_STRUCT_STAT *sbuf2)
150 if (sbuf1->st_ex_uid != sbuf2->st_ex_uid ||
151 sbuf1->st_ex_gid != sbuf2->st_ex_gid ||
152 !check_same_dev_ino(sbuf1, sbuf2)) {
153 return false;
155 return true;
158 /*******************************************************************
159 Show a smb message structure.
160 ********************************************************************/
162 void show_msg(const char *buf)
164 int i;
165 int bcc=0;
167 if (!DEBUGLVL(5))
168 return;
170 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
171 smb_len(buf),
172 (int)CVAL(buf,smb_com),
173 (int)CVAL(buf,smb_rcls),
174 (int)CVAL(buf,smb_reh),
175 (int)SVAL(buf,smb_err),
176 (int)CVAL(buf,smb_flg),
177 (int)SVAL(buf,smb_flg2)));
178 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
179 (int)SVAL(buf,smb_tid),
180 (int)SVAL(buf,smb_pid),
181 (int)SVAL(buf,smb_uid),
182 (int)SVAL(buf,smb_mid)));
183 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
185 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
186 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
187 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
189 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
191 DEBUGADD(5,("smb_bcc=%d\n",bcc));
193 if (DEBUGLEVEL < 10)
194 return;
196 if (DEBUGLEVEL < 50)
197 bcc = MIN(bcc, 512);
199 dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
202 /*******************************************************************
203 Setup only the byte count for a smb message.
204 ********************************************************************/
206 int set_message_bcc(char *buf,int num_bytes)
208 int num_words = CVAL(buf,smb_wct);
209 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
210 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
211 return (smb_size + num_words*2 + num_bytes);
214 /*******************************************************************
215 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
216 Return the bytes added
217 ********************************************************************/
219 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
221 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
222 uint8 *tmp;
224 if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
225 DEBUG(0, ("talloc failed\n"));
226 return -1;
228 *outbuf = tmp;
230 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
231 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
232 return blob.length;
235 /*******************************************************************
236 Reduce a file name, removing .. elements.
237 ********************************************************************/
239 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
241 char *p = NULL;
242 char *str = NULL;
244 DEBUG(3,("dos_clean_name [%s]\n",s));
246 /* remove any double slashes */
247 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
248 if (!str) {
249 return NULL;
252 /* Remove leading .\\ characters */
253 if(strncmp(str, ".\\", 2) == 0) {
254 trim_string(str, ".\\", NULL);
255 if(*str == 0) {
256 str = talloc_strdup(ctx, ".\\");
257 if (!str) {
258 return NULL;
263 while ((p = strstr_m(str,"\\..\\")) != NULL) {
264 char *s1;
266 *p = 0;
267 s1 = p+3;
269 if ((p=strrchr_m(str,'\\')) != NULL) {
270 *p = 0;
271 } else {
272 *str = 0;
274 str = talloc_asprintf(ctx,
275 "%s%s",
276 str,
277 s1);
278 if (!str) {
279 return NULL;
283 trim_string(str,NULL,"\\..");
284 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
287 /*******************************************************************
288 Reduce a file name, removing .. elements.
289 ********************************************************************/
291 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
293 char *p = NULL;
294 char *str = NULL;
296 DEBUG(3,("unix_clean_name [%s]\n",s));
298 /* remove any double slashes */
299 str = talloc_all_string_sub(ctx, s, "//","/");
300 if (!str) {
301 return NULL;
304 /* Remove leading ./ characters */
305 if(strncmp(str, "./", 2) == 0) {
306 trim_string(str, "./", NULL);
307 if(*str == 0) {
308 str = talloc_strdup(ctx, "./");
309 if (!str) {
310 return NULL;
315 while ((p = strstr_m(str,"/../")) != NULL) {
316 char *s1;
318 *p = 0;
319 s1 = p+3;
321 if ((p=strrchr_m(str,'/')) != NULL) {
322 *p = 0;
323 } else {
324 *str = 0;
326 str = talloc_asprintf(ctx,
327 "%s%s",
328 str,
329 s1);
330 if (!str) {
331 return NULL;
335 trim_string(str,NULL,"/..");
336 return talloc_all_string_sub(ctx, str, "/./", "/");
339 char *clean_name(TALLOC_CTX *ctx, const char *s)
341 char *str = dos_clean_name(ctx, s);
342 if (!str) {
343 return NULL;
345 return unix_clean_name(ctx, str);
348 /*******************************************************************
349 Write data into an fd at a given offset. Ignore seek errors.
350 ********************************************************************/
352 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, off_t pos)
354 size_t total=0;
355 ssize_t ret;
357 if (pos == (off_t)-1) {
358 return write_data(fd, buffer, N);
360 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
361 while (total < N) {
362 ret = sys_pwrite(fd,buffer + total,N - total, pos);
363 if (ret == -1 && errno == ESPIPE) {
364 return write_data(fd, buffer + total,N - total);
366 if (ret == -1) {
367 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
368 return -1;
370 if (ret == 0) {
371 return total;
373 total += ret;
374 pos += ret;
376 return (ssize_t)total;
377 #else
378 /* Use lseek and write_data. */
379 if (lseek(fd, pos, SEEK_SET) == -1) {
380 if (errno != ESPIPE) {
381 return -1;
384 return write_data(fd, buffer, N);
385 #endif
388 static int reinit_after_fork_pipe[2] = { -1, -1 };
390 NTSTATUS init_before_fork(void)
392 int ret;
394 ret = pipe(reinit_after_fork_pipe);
395 if (ret == -1) {
396 NTSTATUS status;
398 status = map_nt_error_from_unix_common(errno);
400 DEBUG(0, ("Error creating child_pipe: %s\n",
401 nt_errstr(status)));
403 return status;
406 return NT_STATUS_OK;
410 * Detect died parent by detecting EOF on the pipe
412 static void reinit_after_fork_pipe_handler(struct tevent_context *ev,
413 struct tevent_fd *fde,
414 uint16_t flags,
415 void *private_data)
417 char c;
419 if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) {
421 * we have reached EOF on stdin, which means the
422 * parent has exited. Shutdown the server
424 (void)kill(getpid(), SIGTERM);
429 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
430 struct event_context *ev_ctx,
431 bool parent_longlived)
433 NTSTATUS status = NT_STATUS_OK;
435 if (reinit_after_fork_pipe[1] != -1) {
436 close(reinit_after_fork_pipe[1]);
437 reinit_after_fork_pipe[1] = -1;
440 /* Reset the state of the random
441 * number generation system, so
442 * children do not get the same random
443 * numbers as each other */
444 set_need_random_reseed();
446 /* tdb needs special fork handling */
447 if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
448 DEBUG(0,("tdb_reopen_all failed.\n"));
449 status = NT_STATUS_OPEN_FAILED;
450 goto done;
453 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
454 smb_panic(__location__ ": Failed to re-initialise event context");
457 if (reinit_after_fork_pipe[0] != -1) {
458 struct tevent_fd *fde;
460 fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */,
461 reinit_after_fork_pipe[0], TEVENT_FD_READ,
462 reinit_after_fork_pipe_handler, NULL);
463 if (fde == NULL) {
464 smb_panic(__location__ ": Failed to add reinit_after_fork pipe event");
468 if (msg_ctx) {
470 * For clustering, we need to re-init our ctdbd connection after the
471 * fork
473 status = messaging_reinit(msg_ctx);
474 if (!NT_STATUS_IS_OK(status)) {
475 DEBUG(0,("messaging_reinit() failed: %s\n",
476 nt_errstr(status)));
479 done:
480 return status;
483 /****************************************************************************
484 (Hopefully) efficient array append.
485 ****************************************************************************/
487 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
488 void *element, void *_array, uint32 *num_elements,
489 ssize_t *array_size)
491 void **array = (void **)_array;
493 if (*array_size < 0) {
494 return;
497 if (*array == NULL) {
498 if (*array_size == 0) {
499 *array_size = 128;
502 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
503 goto error;
506 *array = TALLOC(mem_ctx, element_size * (*array_size));
507 if (*array == NULL) {
508 goto error;
512 if (*num_elements == *array_size) {
513 *array_size *= 2;
515 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
516 goto error;
519 *array = TALLOC_REALLOC(mem_ctx, *array,
520 element_size * (*array_size));
522 if (*array == NULL) {
523 goto error;
527 memcpy((char *)(*array) + element_size*(*num_elements),
528 element, element_size);
529 *num_elements += 1;
531 return;
533 error:
534 *num_elements = 0;
535 *array_size = -1;
538 /****************************************************************************
539 Get my own domain name, or "" if we have none.
540 ****************************************************************************/
542 char *get_mydnsdomname(TALLOC_CTX *ctx)
544 const char *domname;
545 char *p;
547 domname = get_mydnsfullname();
548 if (!domname) {
549 return NULL;
552 p = strchr_m(domname, '.');
553 if (p) {
554 p++;
555 return talloc_strdup(ctx, p);
556 } else {
557 return talloc_strdup(ctx, "");
561 /****************************************************************************
562 Interpret a protocol description string, with a default.
563 ****************************************************************************/
565 int interpret_protocol(const char *str,int def)
567 if (strequal(str,"NT1"))
568 return(PROTOCOL_NT1);
569 if (strequal(str,"LANMAN2"))
570 return(PROTOCOL_LANMAN2);
571 if (strequal(str,"LANMAN1"))
572 return(PROTOCOL_LANMAN1);
573 if (strequal(str,"CORE"))
574 return(PROTOCOL_CORE);
575 if (strequal(str,"COREPLUS"))
576 return(PROTOCOL_COREPLUS);
577 if (strequal(str,"CORE+"))
578 return(PROTOCOL_COREPLUS);
580 DEBUG(0,("Unrecognised protocol level %s\n",str));
582 return(def);
586 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
587 /******************************************************************
588 Remove any mount options such as -rsize=2048,wsize=2048 etc.
589 Based on a fix from <Thomas.Hepper@icem.de>.
590 Returns a malloc'ed string.
591 *******************************************************************/
593 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
595 if (*str == '-') {
596 const char *p = str;
597 while(*p && !isspace(*p))
598 p++;
599 while(*p && isspace(*p))
600 p++;
601 if(*p) {
602 return talloc_strdup(ctx, p);
605 return NULL;
608 /*******************************************************************
609 Patch from jkf@soton.ac.uk
610 Split Luke's automount_server into YP lookup and string splitter
611 so can easily implement automount_path().
612 Returns a malloc'ed string.
613 *******************************************************************/
615 #ifdef WITH_NISPLUS_HOME
616 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
618 char *value = NULL;
620 char *nis_map = (char *)lp_nis_home_map_name();
622 char buffer[NIS_MAXATTRVAL + 1];
623 nis_result *result;
624 nis_object *object;
625 entry_obj *entry;
627 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
628 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
630 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
631 if (result->status != NIS_SUCCESS) {
632 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
633 } else {
634 object = result->objects.objects_val;
635 if (object->zo_data.zo_type == ENTRY_OBJ) {
636 entry = &object->zo_data.objdata_u.en_data;
637 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
638 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
640 value = talloc_strdup(ctx,
641 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
642 if (!value) {
643 nis_freeresult(result);
644 return NULL;
646 value = talloc_string_sub(ctx,
647 value,
648 "&",
649 user_name);
653 nis_freeresult(result);
655 if (value) {
656 value = strip_mount_options(ctx, value);
657 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
658 user_name, value));
660 return value;
662 #else /* WITH_NISPLUS_HOME */
664 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
666 char *value = NULL;
668 int nis_error; /* returned by yp all functions */
669 char *nis_result; /* yp_match inits this */
670 int nis_result_len; /* and set this */
671 char *nis_domain; /* yp_get_default_domain inits this */
672 char *nis_map = lp_nis_home_map_name(talloc_tos());
674 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
675 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
676 return NULL;
679 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
681 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
682 strlen(user_name), &nis_result,
683 &nis_result_len)) == 0) {
684 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
685 nis_result[nis_result_len] = '\0';
687 value = talloc_strdup(ctx, nis_result);
688 if (!value) {
689 return NULL;
691 value = strip_mount_options(ctx, value);
692 } else if(nis_error == YPERR_KEY) {
693 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
694 user_name, nis_map));
695 DEBUG(3, ("using defaults for server and home directory\n"));
696 } else {
697 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
698 yperr_string(nis_error), user_name, nis_map));
701 if (value) {
702 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
704 return value;
706 #endif /* WITH_NISPLUS_HOME */
707 #endif
709 /****************************************************************************
710 Check if a process exists. Does this work on all unixes?
711 ****************************************************************************/
713 bool process_exists(const struct server_id pid)
715 if (procid_is_me(&pid)) {
716 return True;
719 if (procid_is_local(&pid)) {
720 return (kill(pid.pid,0) == 0 || errno != ESRCH);
723 #ifdef CLUSTER_SUPPORT
724 return ctdbd_process_exists(messaging_ctdbd_connection(),
725 pid.vnn, pid.pid);
726 #else
727 return False;
728 #endif
731 bool processes_exist(const struct server_id *pids, int num_pids,
732 bool *results)
734 struct server_id *remote_pids = NULL;
735 int *remote_idx = NULL;
736 bool *remote_results = NULL;
737 int i, num_remote_pids;
738 bool result = false;
740 remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
741 if (remote_pids == NULL) {
742 goto fail;
744 remote_idx = talloc_array(talloc_tos(), int, num_pids);
745 if (remote_idx == NULL) {
746 goto fail;
748 remote_results = talloc_array(talloc_tos(), bool, num_pids);
749 if (remote_results == NULL) {
750 goto fail;
753 num_remote_pids = 0;
755 for (i=0; i<num_pids; i++) {
756 if (procid_is_me(&pids[i])) {
757 results[i] = true;
758 continue;
760 if (procid_is_local(&pids[i])) {
761 results[i] = ((kill(pids[i].pid,0) == 0) ||
762 (errno != ESRCH));
763 continue;
766 remote_pids[num_remote_pids] = pids[i];
767 remote_idx[num_remote_pids] = i;
768 num_remote_pids += 1;
771 if (num_remote_pids != 0) {
772 #ifdef CLUSTER_SUPPORT
773 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
774 remote_pids, num_remote_pids,
775 remote_results)) {
776 goto fail;
778 #else
779 for (i=0; i<num_remote_pids; i++) {
780 remote_results[i] = false;
782 #endif
784 for (i=0; i<num_remote_pids; i++) {
785 results[remote_idx[i]] = remote_results[i];
789 result = true;
790 fail:
791 TALLOC_FREE(remote_results);
792 TALLOC_FREE(remote_idx);
793 TALLOC_FREE(remote_pids);
794 return result;
797 /*******************************************************************
798 Convert a uid into a user name.
799 ********************************************************************/
801 const char *uidtoname(uid_t uid)
803 TALLOC_CTX *ctx = talloc_tos();
804 char *name = NULL;
805 struct passwd *pass = NULL;
807 pass = getpwuid_alloc(ctx,uid);
808 if (pass) {
809 name = talloc_strdup(ctx,pass->pw_name);
810 TALLOC_FREE(pass);
811 } else {
812 name = talloc_asprintf(ctx,
813 "%ld",
814 (long int)uid);
816 return name;
819 /*******************************************************************
820 Convert a gid into a group name.
821 ********************************************************************/
823 char *gidtoname(gid_t gid)
825 struct group *grp;
827 grp = getgrgid(gid);
828 if (grp) {
829 return talloc_strdup(talloc_tos(), grp->gr_name);
831 else {
832 return talloc_asprintf(talloc_tos(),
833 "%d",
834 (int)gid);
838 /*******************************************************************
839 Convert a user name into a uid.
840 ********************************************************************/
842 uid_t nametouid(const char *name)
844 struct passwd *pass;
845 char *p;
846 uid_t u;
848 pass = Get_Pwnam_alloc(talloc_tos(), name);
849 if (pass) {
850 u = pass->pw_uid;
851 TALLOC_FREE(pass);
852 return u;
855 u = (uid_t)strtol(name, &p, 0);
856 if ((p != name) && (*p == '\0'))
857 return u;
859 return (uid_t)-1;
862 /*******************************************************************
863 Convert a name to a gid_t if possible. Return -1 if not a group.
864 ********************************************************************/
866 gid_t nametogid(const char *name)
868 struct group *grp;
869 char *p;
870 gid_t g;
872 g = (gid_t)strtol(name, &p, 0);
873 if ((p != name) && (*p == '\0'))
874 return g;
876 grp = getgrnam(name);
877 if (grp)
878 return(grp->gr_gid);
879 return (gid_t)-1;
882 /*******************************************************************
883 Something really nasty happened - panic !
884 ********************************************************************/
886 void smb_panic_s3(const char *why)
888 char *cmd;
889 int result;
891 DEBUG(0,("PANIC (pid %llu): %s\n",
892 (unsigned long long)getpid(), why));
893 log_stack_trace();
895 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
897 * Make sure all children can attach a debugger.
899 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
900 #endif
902 cmd = lp_panic_action(talloc_tos());
903 if (cmd && *cmd) {
904 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
905 result = system(cmd);
907 if (result == -1)
908 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
909 strerror(errno)));
910 else
911 DEBUG(0, ("smb_panic(): action returned status %d\n",
912 WEXITSTATUS(result)));
915 dump_core();
918 /*******************************************************************
919 Print a backtrace of the stack to the debug log. This function
920 DELIBERATELY LEAKS MEMORY. The expectation is that you should
921 exit shortly after calling it.
922 ********************************************************************/
924 #ifdef HAVE_LIBUNWIND_H
925 #include <libunwind.h>
926 #endif
928 #ifdef HAVE_EXECINFO_H
929 #include <execinfo.h>
930 #endif
932 #ifdef HAVE_LIBEXC_H
933 #include <libexc.h>
934 #endif
936 void log_stack_trace(void)
938 #ifdef HAVE_LIBUNWIND
939 /* Try to use libunwind before any other technique since on ia64
940 * libunwind correctly walks the stack in more circumstances than
941 * backtrace.
943 unw_cursor_t cursor;
944 unw_context_t uc;
945 unsigned i = 0;
947 char procname[256];
948 unw_word_t ip, sp, off;
950 procname[sizeof(procname) - 1] = '\0';
952 if (unw_getcontext(&uc) != 0) {
953 goto libunwind_failed;
956 if (unw_init_local(&cursor, &uc) != 0) {
957 goto libunwind_failed;
960 DEBUG(0, ("BACKTRACE:\n"));
962 do {
963 ip = sp = 0;
964 unw_get_reg(&cursor, UNW_REG_IP, &ip);
965 unw_get_reg(&cursor, UNW_REG_SP, &sp);
967 switch (unw_get_proc_name(&cursor,
968 procname, sizeof(procname) - 1, &off) ) {
969 case 0:
970 /* Name found. */
971 case -UNW_ENOMEM:
972 /* Name truncated. */
973 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
974 i, procname, (long long)off,
975 (long long)ip, (long long) sp));
976 break;
977 default:
978 /* case -UNW_ENOINFO: */
979 /* case -UNW_EUNSPEC: */
980 /* No symbol name found. */
981 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
982 i, "<unknown symbol>",
983 (long long)ip, (long long) sp));
985 ++i;
986 } while (unw_step(&cursor) > 0);
988 return;
990 libunwind_failed:
991 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
993 #elif HAVE_BACKTRACE_SYMBOLS
994 void *backtrace_stack[BACKTRACE_STACK_SIZE];
995 size_t backtrace_size;
996 char **backtrace_strings;
998 /* get the backtrace (stack frames) */
999 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1000 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1002 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1003 (unsigned long)backtrace_size));
1005 if (backtrace_strings) {
1006 int i;
1008 for (i = 0; i < backtrace_size; i++)
1009 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1011 /* Leak the backtrace_strings, rather than risk what free() might do */
1014 #elif HAVE_LIBEXC
1016 /* The IRIX libexc library provides an API for unwinding the stack. See
1017 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1018 * since we are about to abort anyway, it hardly matters.
1021 #define NAMESIZE 32 /* Arbitrary */
1023 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1024 char * names[BACKTRACE_STACK_SIZE];
1025 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1027 int i;
1028 int levels;
1030 ZERO_ARRAY(addrs);
1031 ZERO_ARRAY(names);
1032 ZERO_ARRAY(namebuf);
1034 /* We need to be root so we can open our /proc entry to walk
1035 * our stack. It also helps when we want to dump core.
1037 become_root();
1039 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1040 names[i] = namebuf + (i * NAMESIZE);
1043 levels = trace_back_stack(0, addrs, names,
1044 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1046 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1047 for (i = 0; i < levels; i++) {
1048 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1050 #undef NAMESIZE
1052 #else
1053 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1054 #endif
1057 /*******************************************************************
1058 A readdir wrapper which just returns the file name.
1059 ********************************************************************/
1061 const char *readdirname(DIR *p)
1063 struct dirent *ptr;
1064 char *dname;
1066 if (!p)
1067 return(NULL);
1069 ptr = (struct dirent *)readdir(p);
1070 if (!ptr)
1071 return(NULL);
1073 dname = ptr->d_name;
1075 #ifdef NEXT2
1076 if (telldir(p) < 0)
1077 return(NULL);
1078 #endif
1080 #ifdef HAVE_BROKEN_READDIR_NAME
1081 /* using /usr/ucb/cc is BAD */
1082 dname = dname - 2;
1083 #endif
1085 return talloc_strdup(talloc_tos(), dname);
1088 /*******************************************************************
1089 Utility function used to decide if the last component
1090 of a path matches a (possibly wildcarded) entry in a namelist.
1091 ********************************************************************/
1093 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1095 const char *last_component;
1097 /* if we have no list it's obviously not in the path */
1098 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1099 return False;
1102 DEBUG(8, ("is_in_path: %s\n", name));
1104 /* Get the last component of the unix name. */
1105 last_component = strrchr_m(name, '/');
1106 if (!last_component) {
1107 last_component = name;
1108 } else {
1109 last_component++; /* Go past '/' */
1112 for(; namelist->name != NULL; namelist++) {
1113 if(namelist->is_wild) {
1114 if (mask_match(last_component, namelist->name, case_sensitive)) {
1115 DEBUG(8,("is_in_path: mask match succeeded\n"));
1116 return True;
1118 } else {
1119 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1120 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1121 DEBUG(8,("is_in_path: match succeeded\n"));
1122 return True;
1126 DEBUG(8,("is_in_path: match not found\n"));
1127 return False;
1130 /*******************************************************************
1131 Strip a '/' separated list into an array of
1132 name_compare_enties structures suitable for
1133 passing to is_in_path(). We do this for
1134 speed so we can pre-parse all the names in the list
1135 and don't do it for each call to is_in_path().
1136 We also check if the entry contains a wildcard to
1137 remove a potentially expensive call to mask_match
1138 if possible.
1139 ********************************************************************/
1141 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1143 char *name_end;
1144 char *namelist;
1145 char *nameptr;
1146 int num_entries = 0;
1147 int i;
1149 (*ppname_array) = NULL;
1151 if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0')))
1152 return;
1154 namelist = talloc_strdup(talloc_tos(), namelist_in);
1155 if (namelist == NULL) {
1156 DEBUG(0,("set_namearray: talloc fail\n"));
1157 return;
1159 nameptr = namelist;
1161 /* We need to make two passes over the string. The
1162 first to count the number of elements, the second
1163 to split it.
1166 while(*nameptr) {
1167 if ( *nameptr == '/' ) {
1168 /* cope with multiple (useless) /s) */
1169 nameptr++;
1170 continue;
1172 /* anything left? */
1173 if ( *nameptr == '\0' )
1174 break;
1176 /* find the next '/' or consume remaining */
1177 name_end = strchr_m(nameptr, '/');
1178 if (name_end == NULL)
1179 name_end = (char *)nameptr + strlen(nameptr);
1181 /* next segment please */
1182 nameptr = name_end + 1;
1183 num_entries++;
1186 if(num_entries == 0) {
1187 talloc_free(namelist);
1188 return;
1191 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1192 DEBUG(0,("set_namearray: malloc fail\n"));
1193 talloc_free(namelist);
1194 return;
1197 /* Now copy out the names */
1198 nameptr = namelist;
1199 i = 0;
1200 while(*nameptr) {
1201 if ( *nameptr == '/' ) {
1202 /* cope with multiple (useless) /s) */
1203 nameptr++;
1204 continue;
1206 /* anything left? */
1207 if ( *nameptr == '\0' )
1208 break;
1210 /* find the next '/' or consume remaining */
1211 name_end = strchr_m(nameptr, '/');
1212 if (name_end)
1213 *name_end = '\0';
1214 else
1215 name_end = nameptr + strlen(nameptr);
1217 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1218 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1219 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1220 talloc_free(namelist);
1221 return;
1224 /* next segment please */
1225 nameptr = name_end + 1;
1226 i++;
1229 (*ppname_array)[i].name = NULL;
1231 talloc_free(namelist);
1232 return;
1235 #undef DBGC_CLASS
1236 #define DBGC_CLASS DBGC_LOCKING
1238 /****************************************************************************
1239 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1240 is dealt with in posix.c
1241 Returns True if we have information regarding this lock region (and returns
1242 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1243 ****************************************************************************/
1245 bool fcntl_getlock(int fd, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1247 struct flock lock;
1248 int ret;
1250 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1251 fd,(double)*poffset,(double)*pcount,*ptype));
1253 lock.l_type = *ptype;
1254 lock.l_whence = SEEK_SET;
1255 lock.l_start = *poffset;
1256 lock.l_len = *pcount;
1257 lock.l_pid = 0;
1259 ret = sys_fcntl_ptr(fd,F_GETLK,&lock);
1261 if (ret == -1) {
1262 int sav = errno;
1263 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1264 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1265 errno = sav;
1266 return False;
1269 *ptype = lock.l_type;
1270 *poffset = lock.l_start;
1271 *pcount = lock.l_len;
1272 *ppid = lock.l_pid;
1274 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1275 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1276 return True;
1279 #undef DBGC_CLASS
1280 #define DBGC_CLASS DBGC_ALL
1282 /*******************************************************************
1283 Is the name specified one of my netbios names.
1284 Returns true if it is equal, false otherwise.
1285 ********************************************************************/
1287 bool is_myname(const char *s)
1289 int n;
1290 bool ret = False;
1292 for (n=0; my_netbios_names(n); n++) {
1293 if (strequal(my_netbios_names(n), s)) {
1294 ret=True;
1295 break;
1298 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1299 return(ret);
1302 /*******************************************************************
1303 we distinguish between 2K and XP by the "Native Lan Manager" string
1304 WinXP => "Windows 2002 5.1"
1305 WinXP 64bit => "Windows XP 5.2"
1306 Win2k => "Windows 2000 5.0"
1307 NT4 => "Windows NT 4.0"
1308 Win9x => "Windows 4.0"
1309 Windows 2003 doesn't set the native lan manager string but
1310 they do set the domain to "Windows 2003 5.2" (probably a bug).
1311 ********************************************************************/
1313 void ra_lanman_string( const char *native_lanman )
1315 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1316 set_remote_arch( RA_WINXP );
1317 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1318 set_remote_arch( RA_WINXP64 );
1319 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1320 set_remote_arch( RA_WIN2K3 );
1323 static const char *remote_arch_str;
1325 const char *get_remote_arch_str(void)
1327 if (!remote_arch_str) {
1328 return "UNKNOWN";
1330 return remote_arch_str;
1333 /*******************************************************************
1334 Set the horrid remote_arch string based on an enum.
1335 ********************************************************************/
1337 void set_remote_arch(enum remote_arch_types type)
1339 ra_type = type;
1340 switch( type ) {
1341 case RA_WFWG:
1342 remote_arch_str = "WfWg";
1343 break;
1344 case RA_OS2:
1345 remote_arch_str = "OS2";
1346 break;
1347 case RA_WIN95:
1348 remote_arch_str = "Win95";
1349 break;
1350 case RA_WINNT:
1351 remote_arch_str = "WinNT";
1352 break;
1353 case RA_WIN2K:
1354 remote_arch_str = "Win2K";
1355 break;
1356 case RA_WINXP:
1357 remote_arch_str = "WinXP";
1358 break;
1359 case RA_WINXP64:
1360 remote_arch_str = "WinXP64";
1361 break;
1362 case RA_WIN2K3:
1363 remote_arch_str = "Win2K3";
1364 break;
1365 case RA_VISTA:
1366 remote_arch_str = "Vista";
1367 break;
1368 case RA_SAMBA:
1369 remote_arch_str = "Samba";
1370 break;
1371 case RA_CIFSFS:
1372 remote_arch_str = "CIFSFS";
1373 break;
1374 case RA_OSX:
1375 remote_arch_str = "OSX";
1376 break;
1377 default:
1378 ra_type = RA_UNKNOWN;
1379 remote_arch_str = "UNKNOWN";
1380 break;
1383 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1384 remote_arch_str));
1387 /*******************************************************************
1388 Get the remote_arch type.
1389 ********************************************************************/
1391 enum remote_arch_types get_remote_arch(void)
1393 return ra_type;
1396 const char *tab_depth(int level, int depth)
1398 if( CHECK_DEBUGLVL(level) ) {
1399 dbgtext("%*s", depth*4, "");
1401 return "";
1404 /*****************************************************************************
1405 Provide a checksum on a string
1407 Input: s - the null-terminated character string for which the checksum
1408 will be calculated.
1410 Output: The checksum value calculated for s.
1411 *****************************************************************************/
1413 int str_checksum(const char *s)
1415 if (s == NULL)
1416 return 0;
1417 return hash(s, strlen(s), 0);
1420 /*****************************************************************
1421 Zero a memory area then free it. Used to catch bugs faster.
1422 *****************************************************************/
1424 void zero_free(void *p, size_t size)
1426 memset(p, 0, size);
1427 SAFE_FREE(p);
1430 /*****************************************************************
1431 Set our open file limit to a requested max and return the limit.
1432 *****************************************************************/
1434 int set_maxfiles(int requested_max)
1436 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1437 struct rlimit rlp;
1438 int saved_current_limit;
1440 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1441 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1442 strerror(errno) ));
1443 /* just guess... */
1444 return requested_max;
1448 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1449 * account for the extra fd we need
1450 * as well as the log files and standard
1451 * handles etc. Save the limit we want to set in case
1452 * we are running on an OS that doesn't support this limit (AIX)
1453 * which always returns RLIM_INFINITY for rlp.rlim_max.
1456 /* Try raising the hard (max) limit to the requested amount. */
1458 #if defined(RLIM_INFINITY)
1459 if (rlp.rlim_max != RLIM_INFINITY) {
1460 int orig_max = rlp.rlim_max;
1462 if ( rlp.rlim_max < requested_max )
1463 rlp.rlim_max = requested_max;
1465 /* This failing is not an error - many systems (Linux) don't
1466 support our default request of 10,000 open files. JRA. */
1468 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1469 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1470 (int)rlp.rlim_max, strerror(errno) ));
1472 /* Set failed - restore original value from get. */
1473 rlp.rlim_max = orig_max;
1476 #endif
1478 /* Now try setting the soft (current) limit. */
1480 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1482 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1483 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1484 (int)rlp.rlim_cur, strerror(errno) ));
1485 /* just guess... */
1486 return saved_current_limit;
1489 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1490 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1491 strerror(errno) ));
1492 /* just guess... */
1493 return saved_current_limit;
1496 #if defined(RLIM_INFINITY)
1497 if(rlp.rlim_cur == RLIM_INFINITY)
1498 return saved_current_limit;
1499 #endif
1501 if((int)rlp.rlim_cur > saved_current_limit)
1502 return saved_current_limit;
1504 return rlp.rlim_cur;
1505 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1507 * No way to know - just guess...
1509 return requested_max;
1510 #endif
1513 /*****************************************************************
1514 malloc that aborts with smb_panic on fail or zero size.
1515 *****************************************************************/
1517 void *smb_xmalloc_array(size_t size, unsigned int count)
1519 void *p;
1520 if (size == 0) {
1521 smb_panic("smb_xmalloc_array: called with zero size");
1523 if (count >= MAX_ALLOC_SIZE/size) {
1524 smb_panic("smb_xmalloc_array: alloc size too large");
1526 if ((p = SMB_MALLOC(size*count)) == NULL) {
1527 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1528 (unsigned long)size, (unsigned long)count));
1529 smb_panic("smb_xmalloc_array: malloc failed");
1531 return p;
1535 vasprintf that aborts on malloc fail
1538 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1540 int n;
1541 va_list ap2;
1543 va_copy(ap2, ap);
1545 n = vasprintf(ptr, format, ap2);
1546 va_end(ap2);
1547 if (n == -1 || ! *ptr) {
1548 smb_panic("smb_xvasprintf: out of memory");
1550 return n;
1553 /*****************************************************************
1554 Get local hostname and cache result.
1555 *****************************************************************/
1557 char *myhostname(void)
1559 static char *ret;
1560 if (ret == NULL) {
1561 ret = get_myname(NULL);
1563 return ret;
1566 /*****************************************************************
1567 Get local hostname and cache result.
1568 *****************************************************************/
1570 char *myhostname_upper(void)
1572 char *name;
1573 static char *ret;
1574 if (ret == NULL) {
1575 name = get_myname(talloc_tos());
1576 ret = strupper_talloc(NULL, name);
1577 talloc_free(name);
1579 return ret;
1583 * @brief Returns an absolute path to a file concatenating the provided
1584 * @a rootpath and @a basename
1586 * @param name Filename, relative to @a rootpath
1588 * @retval Pointer to a string containing the full path.
1591 static char *xx_path(const char *name, const char *rootpath)
1593 char *fname = NULL;
1595 fname = talloc_strdup(talloc_tos(), rootpath);
1596 if (!fname) {
1597 return NULL;
1599 trim_string(fname,"","/");
1601 if (!directory_exist(fname)) {
1602 if (!mkdir(fname,0755))
1603 DEBUG(1, ("Unable to create directory %s for file %s. "
1604 "Error was %s\n", fname, name, strerror(errno)));
1607 return talloc_asprintf(talloc_tos(),
1608 "%s/%s",
1609 fname,
1610 name);
1614 * @brief Returns an absolute path to a file in the Samba lock directory.
1616 * @param name File to find, relative to LOCKDIR.
1618 * @retval Pointer to a talloc'ed string containing the full path.
1621 char *lock_path(const char *name)
1623 return xx_path(name, lp_lockdir());
1627 * @brief Returns an absolute path to a file in the Samba state directory.
1629 * @param name File to find, relative to STATEDIR.
1631 * @retval Pointer to a talloc'ed string containing the full path.
1634 char *state_path(const char *name)
1636 return xx_path(name, lp_statedir());
1640 * @brief Returns an absolute path to a file in the Samba cache directory.
1642 * @param name File to find, relative to CACHEDIR.
1644 * @retval Pointer to a talloc'ed string containing the full path.
1647 char *cache_path(const char *name)
1649 return xx_path(name, lp_cachedir());
1652 /*******************************************************************
1653 Given a filename - get its directory name
1654 ********************************************************************/
1656 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1657 const char **name)
1659 char *p;
1660 ptrdiff_t len;
1662 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1664 if (p == NULL) {
1665 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1666 return False;
1668 if (name) {
1669 *name = dir;
1671 return True;
1674 len = p-dir;
1676 if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1677 return False;
1679 (*parent)[len] = '\0';
1681 if (name) {
1682 *name = p+1;
1684 return True;
1687 /*******************************************************************
1688 Determine if a pattern contains any Microsoft wildcard characters.
1689 *******************************************************************/
1691 bool ms_has_wild(const char *s)
1693 char c;
1695 if (lp_posix_pathnames()) {
1696 /* With posix pathnames no characters are wild. */
1697 return False;
1700 while ((c = *s++)) {
1701 switch (c) {
1702 case '*':
1703 case '?':
1704 case '<':
1705 case '>':
1706 case '"':
1707 return True;
1710 return False;
1713 bool ms_has_wild_w(const smb_ucs2_t *s)
1715 smb_ucs2_t c;
1716 if (!s) return False;
1717 while ((c = *s++)) {
1718 switch (c) {
1719 case UCS2_CHAR('*'):
1720 case UCS2_CHAR('?'):
1721 case UCS2_CHAR('<'):
1722 case UCS2_CHAR('>'):
1723 case UCS2_CHAR('"'):
1724 return True;
1727 return False;
1730 /*******************************************************************
1731 A wrapper that handles case sensitivity and the special handling
1732 of the ".." name.
1733 *******************************************************************/
1735 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1737 if (ISDOTDOT(string))
1738 string = ".";
1739 if (ISDOT(pattern))
1740 return False;
1742 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1745 /*******************************************************************
1746 A wrapper that handles case sensitivity and the special handling
1747 of the ".." name. Varient that is only called by old search code which requires
1748 pattern translation.
1749 *******************************************************************/
1751 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1753 if (ISDOTDOT(string))
1754 string = ".";
1755 if (ISDOT(pattern))
1756 return False;
1758 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1761 /*******************************************************************
1762 A wrapper that handles a list of patters and calls mask_match()
1763 on each. Returns True if any of the patterns match.
1764 *******************************************************************/
1766 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1768 while (listLen-- > 0) {
1769 if (mask_match(string, *list++, is_case_sensitive))
1770 return True;
1772 return False;
1775 /*********************************************************
1776 Recursive routine that is called by unix_wild_match.
1777 *********************************************************/
1779 static bool unix_do_match(const char *regexp, const char *str)
1781 const char *p;
1783 for( p = regexp; *p && *str; ) {
1785 switch(*p) {
1786 case '?':
1787 str++;
1788 p++;
1789 break;
1791 case '*':
1794 * Look for a character matching
1795 * the one after the '*'.
1797 p++;
1798 if(!*p)
1799 return true; /* Automatic match */
1800 while(*str) {
1802 while(*str && (*p != *str))
1803 str++;
1806 * Patch from weidel@multichart.de. In the case of the regexp
1807 * '*XX*' we want to ensure there are at least 2 'X' characters
1808 * in the string after the '*' for a match to be made.
1812 int matchcount=0;
1815 * Eat all the characters that match, but count how many there were.
1818 while(*str && (*p == *str)) {
1819 str++;
1820 matchcount++;
1824 * Now check that if the regexp had n identical characters that
1825 * matchcount had at least that many matches.
1828 while ( *(p+1) && (*(p+1) == *p)) {
1829 p++;
1830 matchcount--;
1833 if ( matchcount <= 0 )
1834 return false;
1837 str--; /* We've eaten the match char after the '*' */
1839 if(unix_do_match(p, str))
1840 return true;
1842 if(!*str)
1843 return false;
1844 else
1845 str++;
1847 return false;
1849 default:
1850 if(*str != *p)
1851 return false;
1852 str++;
1853 p++;
1854 break;
1858 if(!*p && !*str)
1859 return true;
1861 if (!*p && str[0] == '.' && str[1] == 0)
1862 return true;
1864 if (!*str && *p == '?') {
1865 while (*p == '?')
1866 p++;
1867 return(!*p);
1870 if(!*str && (*p == '*' && p[1] == '\0'))
1871 return true;
1873 return false;
1876 /*******************************************************************
1877 Simple case insensitive interface to a UNIX wildcard matcher.
1878 Returns True if match, False if not.
1879 *******************************************************************/
1881 bool unix_wild_match(const char *pattern, const char *string)
1883 TALLOC_CTX *ctx = talloc_stackframe();
1884 char *p2;
1885 char *s2;
1886 char *p;
1887 bool ret = false;
1889 p2 = talloc_strdup(ctx,pattern);
1890 s2 = talloc_strdup(ctx,string);
1891 if (!p2 || !s2) {
1892 TALLOC_FREE(ctx);
1893 return false;
1895 if (!strlower_m(p2)) {
1896 TALLOC_FREE(ctx);
1897 return false;
1899 if (!strlower_m(s2)) {
1900 TALLOC_FREE(ctx);
1901 return false;
1904 /* Remove any *? and ** from the pattern as they are meaningless */
1905 for(p = p2; *p; p++) {
1906 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1907 memmove(&p[1], &p[2], strlen(&p[2])+1);
1911 if (strequal(p2,"*")) {
1912 TALLOC_FREE(ctx);
1913 return true;
1916 ret = unix_do_match(p2, s2);
1917 TALLOC_FREE(ctx);
1918 return ret;
1921 /**********************************************************************
1922 Converts a name to a fully qualified domain name.
1923 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1924 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1925 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1926 ***********************************************************************/
1928 bool name_to_fqdn(fstring fqdn, const char *name)
1930 char *full = NULL;
1931 struct hostent *hp = gethostbyname(name);
1933 if (!hp || !hp->h_name || !*hp->h_name) {
1934 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1935 fstrcpy(fqdn, name);
1936 return false;
1939 /* Find out if the fqdn is returned as an alias
1940 * to cope with /etc/hosts files where the first
1941 * name is not the fqdn but the short name */
1942 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1943 int i;
1944 for (i = 0; hp->h_aliases[i]; i++) {
1945 if (strchr_m(hp->h_aliases[i], '.')) {
1946 full = hp->h_aliases[i];
1947 break;
1951 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1952 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1953 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1954 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1955 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1956 full = hp->h_name;
1958 if (!full) {
1959 full = hp->h_name;
1962 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1963 fstrcpy(fqdn, full);
1964 return true;
1967 /**********************************************************************
1968 Append a DATA_BLOB to a talloc'ed object
1969 ***********************************************************************/
1971 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1973 size_t old_size = 0;
1974 char *result;
1976 if (blob.length == 0) {
1977 return buf;
1980 if (buf != NULL) {
1981 old_size = talloc_get_size(buf);
1984 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1985 if (result == NULL) {
1986 return NULL;
1989 memcpy(result + old_size, blob.data, blob.length);
1990 return result;
1993 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1995 switch (share_access & ~FILE_SHARE_DELETE) {
1996 case FILE_SHARE_NONE:
1997 return DENY_ALL;
1998 case FILE_SHARE_READ:
1999 return DENY_WRITE;
2000 case FILE_SHARE_WRITE:
2001 return DENY_READ;
2002 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2003 return DENY_NONE;
2005 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2006 return DENY_DOS;
2007 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2008 return DENY_FCB;
2011 return (uint32)-1;
2014 pid_t procid_to_pid(const struct server_id *proc)
2016 return proc->pid;
2019 static uint32 my_vnn = NONCLUSTER_VNN;
2021 void set_my_vnn(uint32 vnn)
2023 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn));
2024 my_vnn = vnn;
2027 uint32 get_my_vnn(void)
2029 return my_vnn;
2032 static uint64_t my_unique_id = 0;
2034 void set_my_unique_id(uint64_t unique_id)
2036 my_unique_id = unique_id;
2039 struct server_id pid_to_procid(pid_t pid)
2041 struct server_id result;
2042 result.pid = pid;
2043 result.task_id = 0;
2044 result.unique_id = my_unique_id;
2045 result.vnn = my_vnn;
2046 return result;
2049 struct server_id procid_self(void)
2051 return pid_to_procid(getpid());
2054 static struct idr_context *task_id_tree;
2056 static int free_task_id(struct server_id *server_id)
2058 idr_remove(task_id_tree, server_id->task_id);
2059 return 0;
2062 /* Return a server_id with a unique task_id element. Free the
2063 * returned pointer to de-allocate the task_id via a talloc destructor
2064 * (ie, use talloc_free()) */
2065 struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx)
2067 struct server_id *server_id;
2068 int task_id;
2069 if (!task_id_tree) {
2070 task_id_tree = idr_init(NULL);
2071 if (!task_id_tree) {
2072 return NULL;
2076 server_id = talloc(mem_ctx, struct server_id);
2078 if (!server_id) {
2079 return NULL;
2081 *server_id = procid_self();
2083 /* 0 is the default server_id, so we need to start with 1 */
2084 task_id = idr_get_new_above(task_id_tree, server_id, 1, INT32_MAX);
2086 if (task_id == -1) {
2087 talloc_free(server_id);
2088 return NULL;
2091 talloc_set_destructor(server_id, free_task_id);
2092 server_id->task_id = task_id;
2093 return server_id;
2096 bool procid_is_me(const struct server_id *pid)
2098 if (pid->pid != getpid())
2099 return False;
2100 if (pid->task_id != 0)
2101 return False;
2102 if (pid->vnn != my_vnn)
2103 return False;
2104 return True;
2107 struct server_id interpret_pid(const char *pid_string)
2109 struct server_id result;
2110 unsigned long long pid;
2111 unsigned int vnn, task_id = 0;
2113 ZERO_STRUCT(result);
2115 /* We accept various forms with 1, 2 or 3 component forms
2116 * because the server_id_str() can print different forms, and
2117 * we want backwards compatibility for scripts that may call
2118 * smbclient. */
2119 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2120 result.vnn = vnn;
2121 result.pid = pid;
2122 result.task_id = task_id;
2123 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2124 result.vnn = vnn;
2125 result.pid = pid;
2126 result.task_id = 0;
2127 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2128 result.vnn = get_my_vnn();
2129 result.pid = pid;
2130 result.task_id = task_id;
2131 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2132 result.vnn = get_my_vnn();
2133 result.pid = pid;
2134 } else {
2135 result.vnn = NONCLUSTER_VNN;
2136 result.pid = (uint64_t)-1;
2138 return result;
2141 char *procid_str_static(const struct server_id *pid)
2143 return server_id_str(talloc_tos(), pid);
2146 bool procid_valid(const struct server_id *pid)
2148 return (pid->pid != (uint64_t)-1);
2151 bool procid_is_local(const struct server_id *pid)
2153 return pid->vnn == my_vnn;
2156 /****************************************************************
2157 Check if an offset into a buffer is safe.
2158 If this returns True it's safe to indirect into the byte at
2159 pointer ptr+off.
2160 ****************************************************************/
2162 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2164 const char *end_base = buf_base + buf_len;
2165 char *end_ptr = ptr + off;
2167 if (!buf_base || !ptr) {
2168 return False;
2171 if (end_base < buf_base || end_ptr < ptr) {
2172 return False; /* wrap. */
2175 if (end_ptr < end_base) {
2176 return True;
2178 return False;
2181 /****************************************************************
2182 Return a safe pointer into a buffer, or NULL.
2183 ****************************************************************/
2185 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2187 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2188 ptr + off : NULL;
2191 /****************************************************************
2192 Return a safe pointer into a string within a buffer, or NULL.
2193 ****************************************************************/
2195 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2197 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2198 return NULL;
2200 /* Check if a valid string exists at this offset. */
2201 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2202 return NULL;
2204 return ptr + off;
2207 /****************************************************************
2208 Return an SVAL at a pointer, or failval if beyond the end.
2209 ****************************************************************/
2211 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2214 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2215 * NOT ptr[2].
2217 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2218 return failval;
2220 return SVAL(ptr,off);
2223 /****************************************************************
2224 Return an IVAL at a pointer, or failval if beyond the end.
2225 ****************************************************************/
2227 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2230 * Note we use off+3 here, not off+4 as IVAL accesses
2231 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2233 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2234 return failval;
2236 return IVAL(ptr,off);
2239 /****************************************************************
2240 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2241 call (they take care of winbind separator and other winbind specific settings).
2242 ****************************************************************/
2244 void split_domain_user(TALLOC_CTX *mem_ctx,
2245 const char *full_name,
2246 char **domain,
2247 char **user)
2249 const char *p = NULL;
2251 p = strchr_m(full_name, '\\');
2253 if (p != NULL) {
2254 *domain = talloc_strndup(mem_ctx, full_name,
2255 PTR_DIFF(p, full_name));
2256 *user = talloc_strdup(mem_ctx, p+1);
2257 } else {
2258 *domain = talloc_strdup(mem_ctx, "");
2259 *user = talloc_strdup(mem_ctx, full_name);
2263 /****************************************************************
2264 strip off leading '\\' from a hostname
2265 ****************************************************************/
2267 const char *strip_hostname(const char *s)
2269 if (!s) {
2270 return NULL;
2273 if (strlen_m(s) < 3) {
2274 return s;
2277 if (s[0] == '\\') s++;
2278 if (s[0] == '\\') s++;
2280 return s;
2283 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2285 if (!NT_STATUS_IS_OK(err1)) {
2286 *result = err1;
2287 return true;
2289 if (!NT_STATUS_IS_OK(err2)) {
2290 *result = err2;
2291 return true;
2293 return false;
2296 int timeval_to_msec(struct timeval t)
2298 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2301 /*******************************************************************
2302 Check a given DOS pathname is valid for a share.
2303 ********************************************************************/
2305 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2307 char *ptr = NULL;
2309 if (!dos_pathname) {
2310 return NULL;
2313 ptr = talloc_strdup(ctx, dos_pathname);
2314 if (!ptr) {
2315 return NULL;
2317 /* Convert any '\' paths to '/' */
2318 unix_format(ptr);
2319 ptr = unix_clean_name(ctx, ptr);
2320 if (!ptr) {
2321 return NULL;
2324 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2325 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2326 ptr += 2;
2328 /* Only absolute paths allowed. */
2329 if (*ptr != '/')
2330 return NULL;
2332 return ptr;
2335 /*******************************************************************
2336 Return True if the filename is one of the special executable types.
2337 ********************************************************************/
2339 bool is_executable(const char *fname)
2341 if ((fname = strrchr_m(fname,'.'))) {
2342 if (strequal(fname,".com") ||
2343 strequal(fname,".dll") ||
2344 strequal(fname,".exe") ||
2345 strequal(fname,".sym")) {
2346 return True;
2349 return False;
2352 /****************************************************************************
2353 Open a file with a share mode - old openX method - map into NTCreate.
2354 ****************************************************************************/
2356 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2357 int deny_mode, int open_func,
2358 uint32 *paccess_mask,
2359 uint32 *pshare_mode,
2360 uint32 *pcreate_disposition,
2361 uint32 *pcreate_options,
2362 uint32_t *pprivate_flags)
2364 uint32 access_mask;
2365 uint32 share_mode;
2366 uint32 create_disposition;
2367 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2368 uint32_t private_flags = 0;
2370 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2371 "open_func = 0x%x\n",
2372 smb_base_fname, (unsigned int)deny_mode,
2373 (unsigned int)open_func ));
2375 /* Create the NT compatible access_mask. */
2376 switch (GET_OPENX_MODE(deny_mode)) {
2377 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2378 case DOS_OPEN_RDONLY:
2379 access_mask = FILE_GENERIC_READ;
2380 break;
2381 case DOS_OPEN_WRONLY:
2382 access_mask = FILE_GENERIC_WRITE;
2383 break;
2384 case DOS_OPEN_RDWR:
2385 case DOS_OPEN_FCB:
2386 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2387 break;
2388 default:
2389 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2390 (unsigned int)GET_OPENX_MODE(deny_mode)));
2391 return False;
2394 /* Create the NT compatible create_disposition. */
2395 switch (open_func) {
2396 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2397 create_disposition = FILE_CREATE;
2398 break;
2400 case OPENX_FILE_EXISTS_OPEN:
2401 create_disposition = FILE_OPEN;
2402 break;
2404 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2405 create_disposition = FILE_OPEN_IF;
2406 break;
2408 case OPENX_FILE_EXISTS_TRUNCATE:
2409 create_disposition = FILE_OVERWRITE;
2410 break;
2412 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2413 create_disposition = FILE_OVERWRITE_IF;
2414 break;
2416 default:
2417 /* From samba4 - to be confirmed. */
2418 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2419 create_disposition = FILE_CREATE;
2420 break;
2422 DEBUG(10,("map_open_params_to_ntcreate: bad "
2423 "open_func 0x%x\n", (unsigned int)open_func));
2424 return False;
2427 /* Create the NT compatible share modes. */
2428 switch (GET_DENY_MODE(deny_mode)) {
2429 case DENY_ALL:
2430 share_mode = FILE_SHARE_NONE;
2431 break;
2433 case DENY_WRITE:
2434 share_mode = FILE_SHARE_READ;
2435 break;
2437 case DENY_READ:
2438 share_mode = FILE_SHARE_WRITE;
2439 break;
2441 case DENY_NONE:
2442 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2443 break;
2445 case DENY_DOS:
2446 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2447 if (is_executable(smb_base_fname)) {
2448 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2449 } else {
2450 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2451 share_mode = FILE_SHARE_READ;
2452 } else {
2453 share_mode = FILE_SHARE_NONE;
2456 break;
2458 case DENY_FCB:
2459 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2460 share_mode = FILE_SHARE_NONE;
2461 break;
2463 default:
2464 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2465 (unsigned int)GET_DENY_MODE(deny_mode) ));
2466 return False;
2469 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2470 "share_mode = 0x%x, create_disposition = 0x%x, "
2471 "create_options = 0x%x private_flags = 0x%x\n",
2472 smb_base_fname,
2473 (unsigned int)access_mask,
2474 (unsigned int)share_mode,
2475 (unsigned int)create_disposition,
2476 (unsigned int)create_options,
2477 (unsigned int)private_flags));
2479 if (paccess_mask) {
2480 *paccess_mask = access_mask;
2482 if (pshare_mode) {
2483 *pshare_mode = share_mode;
2485 if (pcreate_disposition) {
2486 *pcreate_disposition = create_disposition;
2488 if (pcreate_options) {
2489 *pcreate_options = create_options;
2491 if (pprivate_flags) {
2492 *pprivate_flags = private_flags;
2495 return True;
2499 /*************************************************************************
2500 Return a talloced copy of a struct security_unix_token. NULL on fail.
2501 *************************************************************************/
2503 struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
2505 struct security_unix_token *cpy;
2507 cpy = talloc(ctx, struct security_unix_token);
2508 if (!cpy) {
2509 return NULL;
2512 cpy->uid = tok->uid;
2513 cpy->gid = tok->gid;
2514 cpy->ngroups = tok->ngroups;
2515 if (tok->ngroups) {
2516 /* Make this a talloc child of cpy. */
2517 cpy->groups = (gid_t *)talloc_memdup(
2518 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
2519 if (!cpy->groups) {
2520 TALLOC_FREE(cpy);
2521 return NULL;
2523 } else {
2524 cpy->groups = NULL;
2526 return cpy;