Add two flags to allow for handling of Extended Signatures (Session Key Protection...
[Samba/gebeck_regimport.git] / source3 / lib / util.c
blob9c380c5a02d9442d120e5444141b272e0d6a9b88
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 strlower_m(p2);
1896 strlower_m(s2);
1898 /* Remove any *? and ** from the pattern as they are meaningless */
1899 for(p = p2; *p; p++) {
1900 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1901 memmove(&p[1], &p[2], strlen(&p[2])+1);
1905 if (strequal(p2,"*")) {
1906 TALLOC_FREE(ctx);
1907 return true;
1910 ret = unix_do_match(p2, s2);
1911 TALLOC_FREE(ctx);
1912 return ret;
1915 /**********************************************************************
1916 Converts a name to a fully qualified domain name.
1917 Returns true if lookup succeeded, false if not (then fqdn is set to name)
1918 Note we deliberately use gethostbyname here, not getaddrinfo as we want
1919 to examine the h_aliases and I don't know how to do that with getaddrinfo.
1920 ***********************************************************************/
1922 bool name_to_fqdn(fstring fqdn, const char *name)
1924 char *full = NULL;
1925 struct hostent *hp = gethostbyname(name);
1927 if (!hp || !hp->h_name || !*hp->h_name) {
1928 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1929 fstrcpy(fqdn, name);
1930 return false;
1933 /* Find out if the fqdn is returned as an alias
1934 * to cope with /etc/hosts files where the first
1935 * name is not the fqdn but the short name */
1936 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1937 int i;
1938 for (i = 0; hp->h_aliases[i]; i++) {
1939 if (strchr_m(hp->h_aliases[i], '.')) {
1940 full = hp->h_aliases[i];
1941 break;
1945 if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1946 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1947 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1948 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
1949 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
1950 full = hp->h_name;
1952 if (!full) {
1953 full = hp->h_name;
1956 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1957 fstrcpy(fqdn, full);
1958 return true;
1961 /**********************************************************************
1962 Append a DATA_BLOB to a talloc'ed object
1963 ***********************************************************************/
1965 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1967 size_t old_size = 0;
1968 char *result;
1970 if (blob.length == 0) {
1971 return buf;
1974 if (buf != NULL) {
1975 old_size = talloc_get_size(buf);
1978 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1979 if (result == NULL) {
1980 return NULL;
1983 memcpy(result + old_size, blob.data, blob.length);
1984 return result;
1987 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1989 switch (share_access & ~FILE_SHARE_DELETE) {
1990 case FILE_SHARE_NONE:
1991 return DENY_ALL;
1992 case FILE_SHARE_READ:
1993 return DENY_WRITE;
1994 case FILE_SHARE_WRITE:
1995 return DENY_READ;
1996 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1997 return DENY_NONE;
1999 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2000 return DENY_DOS;
2001 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2002 return DENY_FCB;
2005 return (uint32)-1;
2008 pid_t procid_to_pid(const struct server_id *proc)
2010 return proc->pid;
2013 static uint32 my_vnn = NONCLUSTER_VNN;
2015 void set_my_vnn(uint32 vnn)
2017 DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn));
2018 my_vnn = vnn;
2021 uint32 get_my_vnn(void)
2023 return my_vnn;
2026 static uint64_t my_unique_id = 0;
2028 void set_my_unique_id(uint64_t unique_id)
2030 my_unique_id = unique_id;
2033 struct server_id pid_to_procid(pid_t pid)
2035 struct server_id result;
2036 result.pid = pid;
2037 result.task_id = 0;
2038 result.unique_id = my_unique_id;
2039 result.vnn = my_vnn;
2040 return result;
2043 struct server_id procid_self(void)
2045 return pid_to_procid(getpid());
2048 static struct idr_context *task_id_tree;
2050 static int free_task_id(struct server_id *server_id)
2052 idr_remove(task_id_tree, server_id->task_id);
2053 return 0;
2056 /* Return a server_id with a unique task_id element. Free the
2057 * returned pointer to de-allocate the task_id via a talloc destructor
2058 * (ie, use talloc_free()) */
2059 struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx)
2061 struct server_id *server_id;
2062 int task_id;
2063 if (!task_id_tree) {
2064 task_id_tree = idr_init(NULL);
2065 if (!task_id_tree) {
2066 return NULL;
2070 server_id = talloc(mem_ctx, struct server_id);
2072 if (!server_id) {
2073 return NULL;
2075 *server_id = procid_self();
2077 /* 0 is the default server_id, so we need to start with 1 */
2078 task_id = idr_get_new_above(task_id_tree, server_id, 1, INT32_MAX);
2080 if (task_id == -1) {
2081 talloc_free(server_id);
2082 return NULL;
2085 talloc_set_destructor(server_id, free_task_id);
2086 server_id->task_id = task_id;
2087 return server_id;
2090 bool procid_is_me(const struct server_id *pid)
2092 if (pid->pid != getpid())
2093 return False;
2094 if (pid->task_id != 0)
2095 return False;
2096 if (pid->vnn != my_vnn)
2097 return False;
2098 return True;
2101 struct server_id interpret_pid(const char *pid_string)
2103 struct server_id result;
2104 unsigned long long pid;
2105 unsigned int vnn, task_id = 0;
2107 ZERO_STRUCT(result);
2109 /* We accept various forms with 1, 2 or 3 component forms
2110 * because the server_id_str() can print different forms, and
2111 * we want backwards compatibility for scripts that may call
2112 * smbclient. */
2113 if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2114 result.vnn = vnn;
2115 result.pid = pid;
2116 result.task_id = task_id;
2117 } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2118 result.vnn = vnn;
2119 result.pid = pid;
2120 result.task_id = 0;
2121 } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2122 result.vnn = get_my_vnn();
2123 result.pid = pid;
2124 result.task_id = task_id;
2125 } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2126 result.vnn = get_my_vnn();
2127 result.pid = pid;
2128 } else {
2129 result.vnn = NONCLUSTER_VNN;
2130 result.pid = (uint64_t)-1;
2132 return result;
2135 char *procid_str_static(const struct server_id *pid)
2137 return server_id_str(talloc_tos(), pid);
2140 bool procid_valid(const struct server_id *pid)
2142 return (pid->pid != (uint64_t)-1);
2145 bool procid_is_local(const struct server_id *pid)
2147 return pid->vnn == my_vnn;
2150 /****************************************************************
2151 Check if an offset into a buffer is safe.
2152 If this returns True it's safe to indirect into the byte at
2153 pointer ptr+off.
2154 ****************************************************************/
2156 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2158 const char *end_base = buf_base + buf_len;
2159 char *end_ptr = ptr + off;
2161 if (!buf_base || !ptr) {
2162 return False;
2165 if (end_base < buf_base || end_ptr < ptr) {
2166 return False; /* wrap. */
2169 if (end_ptr < end_base) {
2170 return True;
2172 return False;
2175 /****************************************************************
2176 Return a safe pointer into a buffer, or NULL.
2177 ****************************************************************/
2179 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2181 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2182 ptr + off : NULL;
2185 /****************************************************************
2186 Return a safe pointer into a string within a buffer, or NULL.
2187 ****************************************************************/
2189 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2191 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2192 return NULL;
2194 /* Check if a valid string exists at this offset. */
2195 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2196 return NULL;
2198 return ptr + off;
2201 /****************************************************************
2202 Return an SVAL at a pointer, or failval if beyond the end.
2203 ****************************************************************/
2205 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2208 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2209 * NOT ptr[2].
2211 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2212 return failval;
2214 return SVAL(ptr,off);
2217 /****************************************************************
2218 Return an IVAL at a pointer, or failval if beyond the end.
2219 ****************************************************************/
2221 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2224 * Note we use off+3 here, not off+4 as IVAL accesses
2225 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2227 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2228 return failval;
2230 return IVAL(ptr,off);
2233 /****************************************************************
2234 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2235 call (they take care of winbind separator and other winbind specific settings).
2236 ****************************************************************/
2238 void split_domain_user(TALLOC_CTX *mem_ctx,
2239 const char *full_name,
2240 char **domain,
2241 char **user)
2243 const char *p = NULL;
2245 p = strchr_m(full_name, '\\');
2247 if (p != NULL) {
2248 *domain = talloc_strndup(mem_ctx, full_name,
2249 PTR_DIFF(p, full_name));
2250 *user = talloc_strdup(mem_ctx, p+1);
2251 } else {
2252 *domain = talloc_strdup(mem_ctx, "");
2253 *user = talloc_strdup(mem_ctx, full_name);
2257 /****************************************************************
2258 strip off leading '\\' from a hostname
2259 ****************************************************************/
2261 const char *strip_hostname(const char *s)
2263 if (!s) {
2264 return NULL;
2267 if (strlen_m(s) < 3) {
2268 return s;
2271 if (s[0] == '\\') s++;
2272 if (s[0] == '\\') s++;
2274 return s;
2277 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2279 if (!NT_STATUS_IS_OK(err1)) {
2280 *result = err1;
2281 return true;
2283 if (!NT_STATUS_IS_OK(err2)) {
2284 *result = err2;
2285 return true;
2287 return false;
2290 int timeval_to_msec(struct timeval t)
2292 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2295 /*******************************************************************
2296 Check a given DOS pathname is valid for a share.
2297 ********************************************************************/
2299 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2301 char *ptr = NULL;
2303 if (!dos_pathname) {
2304 return NULL;
2307 ptr = talloc_strdup(ctx, dos_pathname);
2308 if (!ptr) {
2309 return NULL;
2311 /* Convert any '\' paths to '/' */
2312 unix_format(ptr);
2313 ptr = unix_clean_name(ctx, ptr);
2314 if (!ptr) {
2315 return NULL;
2318 /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2319 if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2320 ptr += 2;
2322 /* Only absolute paths allowed. */
2323 if (*ptr != '/')
2324 return NULL;
2326 return ptr;
2329 /*******************************************************************
2330 Return True if the filename is one of the special executable types.
2331 ********************************************************************/
2333 bool is_executable(const char *fname)
2335 if ((fname = strrchr_m(fname,'.'))) {
2336 if (strequal(fname,".com") ||
2337 strequal(fname,".dll") ||
2338 strequal(fname,".exe") ||
2339 strequal(fname,".sym")) {
2340 return True;
2343 return False;
2346 /****************************************************************************
2347 Open a file with a share mode - old openX method - map into NTCreate.
2348 ****************************************************************************/
2350 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2351 int deny_mode, int open_func,
2352 uint32 *paccess_mask,
2353 uint32 *pshare_mode,
2354 uint32 *pcreate_disposition,
2355 uint32 *pcreate_options,
2356 uint32_t *pprivate_flags)
2358 uint32 access_mask;
2359 uint32 share_mode;
2360 uint32 create_disposition;
2361 uint32 create_options = FILE_NON_DIRECTORY_FILE;
2362 uint32_t private_flags = 0;
2364 DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2365 "open_func = 0x%x\n",
2366 smb_base_fname, (unsigned int)deny_mode,
2367 (unsigned int)open_func ));
2369 /* Create the NT compatible access_mask. */
2370 switch (GET_OPENX_MODE(deny_mode)) {
2371 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2372 case DOS_OPEN_RDONLY:
2373 access_mask = FILE_GENERIC_READ;
2374 break;
2375 case DOS_OPEN_WRONLY:
2376 access_mask = FILE_GENERIC_WRITE;
2377 break;
2378 case DOS_OPEN_RDWR:
2379 case DOS_OPEN_FCB:
2380 access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2381 break;
2382 default:
2383 DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2384 (unsigned int)GET_OPENX_MODE(deny_mode)));
2385 return False;
2388 /* Create the NT compatible create_disposition. */
2389 switch (open_func) {
2390 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2391 create_disposition = FILE_CREATE;
2392 break;
2394 case OPENX_FILE_EXISTS_OPEN:
2395 create_disposition = FILE_OPEN;
2396 break;
2398 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2399 create_disposition = FILE_OPEN_IF;
2400 break;
2402 case OPENX_FILE_EXISTS_TRUNCATE:
2403 create_disposition = FILE_OVERWRITE;
2404 break;
2406 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2407 create_disposition = FILE_OVERWRITE_IF;
2408 break;
2410 default:
2411 /* From samba4 - to be confirmed. */
2412 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2413 create_disposition = FILE_CREATE;
2414 break;
2416 DEBUG(10,("map_open_params_to_ntcreate: bad "
2417 "open_func 0x%x\n", (unsigned int)open_func));
2418 return False;
2421 /* Create the NT compatible share modes. */
2422 switch (GET_DENY_MODE(deny_mode)) {
2423 case DENY_ALL:
2424 share_mode = FILE_SHARE_NONE;
2425 break;
2427 case DENY_WRITE:
2428 share_mode = FILE_SHARE_READ;
2429 break;
2431 case DENY_READ:
2432 share_mode = FILE_SHARE_WRITE;
2433 break;
2435 case DENY_NONE:
2436 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2437 break;
2439 case DENY_DOS:
2440 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2441 if (is_executable(smb_base_fname)) {
2442 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2443 } else {
2444 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2445 share_mode = FILE_SHARE_READ;
2446 } else {
2447 share_mode = FILE_SHARE_NONE;
2450 break;
2452 case DENY_FCB:
2453 private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2454 share_mode = FILE_SHARE_NONE;
2455 break;
2457 default:
2458 DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2459 (unsigned int)GET_DENY_MODE(deny_mode) ));
2460 return False;
2463 DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2464 "share_mode = 0x%x, create_disposition = 0x%x, "
2465 "create_options = 0x%x private_flags = 0x%x\n",
2466 smb_base_fname,
2467 (unsigned int)access_mask,
2468 (unsigned int)share_mode,
2469 (unsigned int)create_disposition,
2470 (unsigned int)create_options,
2471 (unsigned int)private_flags));
2473 if (paccess_mask) {
2474 *paccess_mask = access_mask;
2476 if (pshare_mode) {
2477 *pshare_mode = share_mode;
2479 if (pcreate_disposition) {
2480 *pcreate_disposition = create_disposition;
2482 if (pcreate_options) {
2483 *pcreate_options = create_options;
2485 if (pprivate_flags) {
2486 *pprivate_flags = private_flags;
2489 return True;
2493 /*************************************************************************
2494 Return a talloced copy of a struct security_unix_token. NULL on fail.
2495 *************************************************************************/
2497 struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
2499 struct security_unix_token *cpy;
2501 cpy = talloc(ctx, struct security_unix_token);
2502 if (!cpy) {
2503 return NULL;
2506 cpy->uid = tok->uid;
2507 cpy->gid = tok->gid;
2508 cpy->ngroups = tok->ngroups;
2509 if (tok->ngroups) {
2510 /* Make this a talloc child of cpy. */
2511 cpy->groups = (gid_t *)talloc_memdup(
2512 cpy, tok->groups, tok->ngroups * sizeof(gid_t));
2513 if (!cpy->groups) {
2514 TALLOC_FREE(cpy);
2515 return NULL;
2517 } else {
2518 cpy->groups = NULL;
2520 return cpy;