9d3d787d639a91ab6eeee02237222d8bc10c7f7d
[samba.git] / source3 / lib / util.c
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
9
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.
14
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.
19
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/>.
22 */
23
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"
33
34 #ifdef HAVE_SYS_PRCTL_H
35 #include <sys/prctl.h>
36 #endif
37
38 /* Max allowable allococation - 256mb - 0x10000000 */
39 #define MAX_ALLOC_SIZE (1024*1024*256)
40
41 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
42 #ifdef WITH_NISPLUS_HOME
43 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
44 /*
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.
50  */
51
52 #if defined(GROUP)
53 #undef GROUP
54 #endif
55
56 #if defined(GROUP_OBJ)
57 #undef GROUP_OBJ
58 #endif
59
60 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
61
62 #include <rpcsvc/nis.h>
63
64 #endif /* WITH_NISPLUS_HOME */
65 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
66
67 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
68
69 enum protocol_types get_Protocol(void)
70 {
71         return Protocol;
72 }
73
74 void set_Protocol(enum protocol_types  p)
75 {
76         Protocol = p;
77 }
78
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
80
81 void gfree_all( void )
82 {
83         gfree_names();
84         gfree_loadparm();
85         gfree_charcnv();
86         gfree_interfaces();
87         gfree_debugsyms();
88 }
89
90 /*******************************************************************
91  Check if a file exists - call vfs_file_exist for samba files.
92 ********************************************************************/
93
94 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
95                      bool fake_dir_create_times)
96 {
97         SMB_STRUCT_STAT st;
98         if (!sbuf)
99                 sbuf = &st;
100
101         if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
102                 return(False);
103
104         return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
105 }
106
107 /*******************************************************************
108  Check if a unix domain socket exists - call vfs_file_exist for samba files.
109 ********************************************************************/
110
111 bool socket_exist(const char *fname)
112 {
113         SMB_STRUCT_STAT st;
114         if (sys_stat(fname, &st, false) != 0)
115                 return(False);
116
117         return S_ISSOCK(st.st_ex_mode);
118 }
119
120 /*******************************************************************
121  Returns the size in bytes of the named given the stat struct.
122 ********************************************************************/
123
124 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
125 {
126         return sbuf->st_ex_size;
127 }
128
129 /*******************************************************************
130  Show a smb message structure.
131 ********************************************************************/
132
133 void show_msg(const char *buf)
134 {
135         int i;
136         int bcc=0;
137
138         if (!DEBUGLVL(5))
139                 return;
140
141         DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
142                         smb_len(buf),
143                         (int)CVAL(buf,smb_com),
144                         (int)CVAL(buf,smb_rcls),
145                         (int)CVAL(buf,smb_reh),
146                         (int)SVAL(buf,smb_err),
147                         (int)CVAL(buf,smb_flg),
148                         (int)SVAL(buf,smb_flg2)));
149         DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
150                         (int)SVAL(buf,smb_tid),
151                         (int)SVAL(buf,smb_pid),
152                         (int)SVAL(buf,smb_uid),
153                         (int)SVAL(buf,smb_mid)));
154         DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
155
156         for (i=0;i<(int)CVAL(buf,smb_wct);i++)
157                 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
158                         SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
159
160         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
161
162         DEBUGADD(5,("smb_bcc=%d\n",bcc));
163
164         if (DEBUGLEVEL < 10)
165                 return;
166
167         if (DEBUGLEVEL < 50)
168                 bcc = MIN(bcc, 512);
169
170         dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
171 }
172
173 /*******************************************************************
174  Setup only the byte count for a smb message.
175 ********************************************************************/
176
177 int set_message_bcc(char *buf,int num_bytes)
178 {
179         int num_words = CVAL(buf,smb_wct);
180         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
181         _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
182         return (smb_size + num_words*2 + num_bytes);
183 }
184
185 /*******************************************************************
186  Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
187  Return the bytes added
188 ********************************************************************/
189
190 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
191 {
192         size_t newlen = smb_len(*outbuf) + 4 + blob.length;
193         uint8 *tmp;
194
195         if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
196                 DEBUG(0, ("talloc failed\n"));
197                 return -1;
198         }
199         *outbuf = tmp;
200
201         memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
202         set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
203         return blob.length;
204 }
205
206 /*******************************************************************
207  Reduce a file name, removing .. elements.
208 ********************************************************************/
209
210 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
211 {
212         char *p = NULL;
213         char *str = NULL;
214
215         DEBUG(3,("dos_clean_name [%s]\n",s));
216
217         /* remove any double slashes */
218         str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
219         if (!str) {
220                 return NULL;
221         }
222
223         /* Remove leading .\\ characters */
224         if(strncmp(str, ".\\", 2) == 0) {
225                 trim_string(str, ".\\", NULL);
226                 if(*str == 0) {
227                         str = talloc_strdup(ctx, ".\\");
228                         if (!str) {
229                                 return NULL;
230                         }
231                 }
232         }
233
234         while ((p = strstr_m(str,"\\..\\")) != NULL) {
235                 char *s1;
236
237                 *p = 0;
238                 s1 = p+3;
239
240                 if ((p=strrchr_m(str,'\\')) != NULL) {
241                         *p = 0;
242                 } else {
243                         *str = 0;
244                 }
245                 str = talloc_asprintf(ctx,
246                                 "%s%s",
247                                 str,
248                                 s1);
249                 if (!str) {
250                         return NULL;
251                 }
252         }
253
254         trim_string(str,NULL,"\\..");
255         return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
256 }
257
258 /*******************************************************************
259  Reduce a file name, removing .. elements.
260 ********************************************************************/
261
262 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
263 {
264         char *p = NULL;
265         char *str = NULL;
266
267         DEBUG(3,("unix_clean_name [%s]\n",s));
268
269         /* remove any double slashes */
270         str = talloc_all_string_sub(ctx, s, "//","/");
271         if (!str) {
272                 return NULL;
273         }
274
275         /* Remove leading ./ characters */
276         if(strncmp(str, "./", 2) == 0) {
277                 trim_string(str, "./", NULL);
278                 if(*str == 0) {
279                         str = talloc_strdup(ctx, "./");
280                         if (!str) {
281                                 return NULL;
282                         }
283                 }
284         }
285
286         while ((p = strstr_m(str,"/../")) != NULL) {
287                 char *s1;
288
289                 *p = 0;
290                 s1 = p+3;
291
292                 if ((p=strrchr_m(str,'/')) != NULL) {
293                         *p = 0;
294                 } else {
295                         *str = 0;
296                 }
297                 str = talloc_asprintf(ctx,
298                                 "%s%s",
299                                 str,
300                                 s1);
301                 if (!str) {
302                         return NULL;
303                 }
304         }
305
306         trim_string(str,NULL,"/..");
307         return talloc_all_string_sub(ctx, str, "/./", "/");
308 }
309
310 char *clean_name(TALLOC_CTX *ctx, const char *s)
311 {
312         char *str = dos_clean_name(ctx, s);
313         if (!str) {
314                 return NULL;
315         }
316         return unix_clean_name(ctx, str);
317 }
318
319 /*******************************************************************
320  Write data into an fd at a given offset. Ignore seek errors.
321 ********************************************************************/
322
323 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
324 {
325         size_t total=0;
326         ssize_t ret;
327
328         if (pos == (SMB_OFF_T)-1) {
329                 return write_data(fd, buffer, N);
330         }
331 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
332         while (total < N) {
333                 ret = sys_pwrite(fd,buffer + total,N - total, pos);
334                 if (ret == -1 && errno == ESPIPE) {
335                         return write_data(fd, buffer + total,N - total);
336                 }
337                 if (ret == -1) {
338                         DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
339                         return -1;
340                 }
341                 if (ret == 0) {
342                         return total;
343                 }
344                 total += ret;
345                 pos += ret;
346         }
347         return (ssize_t)total;
348 #else
349         /* Use lseek and write_data. */
350         if (sys_lseek(fd, pos, SEEK_SET) == -1) {
351                 if (errno != ESPIPE) {
352                         return -1;
353                 }
354         }
355         return write_data(fd, buffer, N);
356 #endif
357 }
358
359 static int reinit_after_fork_pipe[2] = { -1, -1 };
360
361 NTSTATUS init_before_fork(void)
362 {
363         int ret;
364
365         ret = pipe(reinit_after_fork_pipe);
366         if (ret == -1) {
367                 NTSTATUS status;
368
369                 status = map_nt_error_from_unix_common(errno);
370
371                 DEBUG(0, ("Error creating child_pipe: %s\n",
372                           nt_errstr(status)));
373
374                 return status;
375         }
376
377         return NT_STATUS_OK;
378 }
379
380 /**
381  * Detect died parent by detecting EOF on the pipe
382  */
383 static void reinit_after_fork_pipe_handler(struct tevent_context *ev,
384                                            struct tevent_fd *fde,
385                                            uint16_t flags,
386                                            void *private_data)
387 {
388         char c;
389
390         if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) {
391                 /*
392                  * we have reached EOF on stdin, which means the
393                  * parent has exited. Shutdown the server
394                  */
395                 (void)kill(getpid(), SIGTERM);
396         }
397 }
398
399
400 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
401                            struct event_context *ev_ctx,
402                            bool parent_longlived)
403 {
404         NTSTATUS status = NT_STATUS_OK;
405
406         if (reinit_after_fork_pipe[1] != -1) {
407                 close(reinit_after_fork_pipe[1]);
408                 reinit_after_fork_pipe[1] = -1;
409         }
410
411         /* Reset the state of the random
412          * number generation system, so
413          * children do not get the same random
414          * numbers as each other */
415         set_need_random_reseed();
416
417         /* tdb needs special fork handling */
418         if (tdb_reopen_all(parent_longlived ? 1 : 0) != 0) {
419                 DEBUG(0,("tdb_reopen_all failed.\n"));
420                 status = NT_STATUS_OPEN_FAILED;
421                 goto done;
422         }
423
424         if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
425                 smb_panic(__location__ ": Failed to re-initialise event context");
426         }
427
428         if (reinit_after_fork_pipe[0] != -1) {
429                 struct tevent_fd *fde;
430
431                 fde = tevent_add_fd(ev_ctx, ev_ctx /* TALLOC_CTX */,
432                                     reinit_after_fork_pipe[0], TEVENT_FD_READ,
433                                     reinit_after_fork_pipe_handler, NULL);
434                 if (fde == NULL) {
435                         smb_panic(__location__ ": Failed to add reinit_after_fork pipe event");
436                 }
437         }
438
439         if (msg_ctx) {
440                 /*
441                  * For clustering, we need to re-init our ctdbd connection after the
442                  * fork
443                  */
444                 status = messaging_reinit(msg_ctx);
445                 if (!NT_STATUS_IS_OK(status)) {
446                         DEBUG(0,("messaging_reinit() failed: %s\n",
447                                  nt_errstr(status)));
448                 }
449         }
450  done:
451         return status;
452 }
453
454 /****************************************************************************
455  (Hopefully) efficient array append.
456 ****************************************************************************/
457
458 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
459                         void *element, void *_array, uint32 *num_elements,
460                         ssize_t *array_size)
461 {
462         void **array = (void **)_array;
463
464         if (*array_size < 0) {
465                 return;
466         }
467
468         if (*array == NULL) {
469                 if (*array_size == 0) {
470                         *array_size = 128;
471                 }
472
473                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
474                         goto error;
475                 }
476
477                 *array = TALLOC(mem_ctx, element_size * (*array_size));
478                 if (*array == NULL) {
479                         goto error;
480                 }
481         }
482
483         if (*num_elements == *array_size) {
484                 *array_size *= 2;
485
486                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
487                         goto error;
488                 }
489
490                 *array = TALLOC_REALLOC(mem_ctx, *array,
491                                         element_size * (*array_size));
492
493                 if (*array == NULL) {
494                         goto error;
495                 }
496         }
497
498         memcpy((char *)(*array) + element_size*(*num_elements),
499                element, element_size);
500         *num_elements += 1;
501
502         return;
503
504  error:
505         *num_elements = 0;
506         *array_size = -1;
507 }
508
509 /****************************************************************************
510  Get my own domain name, or "" if we have none.
511 ****************************************************************************/
512
513 char *get_mydnsdomname(TALLOC_CTX *ctx)
514 {
515         const char *domname;
516         char *p;
517
518         domname = get_mydnsfullname();
519         if (!domname) {
520                 return NULL;
521         }
522
523         p = strchr_m(domname, '.');
524         if (p) {
525                 p++;
526                 return talloc_strdup(ctx, p);
527         } else {
528                 return talloc_strdup(ctx, "");
529         }
530 }
531
532 /****************************************************************************
533  Interpret a protocol description string, with a default.
534 ****************************************************************************/
535
536 int interpret_protocol(const char *str,int def)
537 {
538         if (strequal(str,"NT1"))
539                 return(PROTOCOL_NT1);
540         if (strequal(str,"LANMAN2"))
541                 return(PROTOCOL_LANMAN2);
542         if (strequal(str,"LANMAN1"))
543                 return(PROTOCOL_LANMAN1);
544         if (strequal(str,"CORE"))
545                 return(PROTOCOL_CORE);
546         if (strequal(str,"COREPLUS"))
547                 return(PROTOCOL_COREPLUS);
548         if (strequal(str,"CORE+"))
549                 return(PROTOCOL_COREPLUS);
550
551         DEBUG(0,("Unrecognised protocol level %s\n",str));
552
553         return(def);
554 }
555
556
557 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
558 /******************************************************************
559  Remove any mount options such as -rsize=2048,wsize=2048 etc.
560  Based on a fix from <Thomas.Hepper@icem.de>.
561  Returns a malloc'ed string.
562 *******************************************************************/
563
564 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
565 {
566         if (*str == '-') {
567                 const char *p = str;
568                 while(*p && !isspace(*p))
569                         p++;
570                 while(*p && isspace(*p))
571                         p++;
572                 if(*p) {
573                         return talloc_strdup(ctx, p);
574                 }
575         }
576         return NULL;
577 }
578
579 /*******************************************************************
580  Patch from jkf@soton.ac.uk
581  Split Luke's automount_server into YP lookup and string splitter
582  so can easily implement automount_path().
583  Returns a malloc'ed string.
584 *******************************************************************/
585
586 #ifdef WITH_NISPLUS_HOME
587 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
588 {
589         char *value = NULL;
590
591         char *nis_map = (char *)lp_nis_home_map_name();
592
593         char buffer[NIS_MAXATTRVAL + 1];
594         nis_result *result;
595         nis_object *object;
596         entry_obj  *entry;
597
598         snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
599         DEBUG(5, ("NIS+ querystring: %s\n", buffer));
600
601         if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
602                 if (result->status != NIS_SUCCESS) {
603                         DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
604                 } else {
605                         object = result->objects.objects_val;
606                         if (object->zo_data.zo_type == ENTRY_OBJ) {
607                                 entry = &object->zo_data.objdata_u.en_data;
608                                 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
609                                 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
610
611                                 value = talloc_strdup(ctx,
612                                                 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
613                                 if (!value) {
614                                         nis_freeresult(result);
615                                         return NULL;
616                                 }
617                                 value = talloc_string_sub(ctx,
618                                                 value,
619                                                 "&",
620                                                 user_name);
621                         }
622                 }
623         }
624         nis_freeresult(result);
625
626         if (value) {
627                 value = strip_mount_options(ctx, value);
628                 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
629                                         user_name, value));
630         }
631         return value;
632 }
633 #else /* WITH_NISPLUS_HOME */
634
635 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
636 {
637         char *value = NULL;
638
639         int nis_error;        /* returned by yp all functions */
640         char *nis_result;     /* yp_match inits this */
641         int nis_result_len;  /* and set this */
642         char *nis_domain;     /* yp_get_default_domain inits this */
643         char *nis_map = (char *)lp_nis_home_map_name();
644
645         if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
646                 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
647                 return NULL;
648         }
649
650         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
651
652         if ((nis_error = yp_match(nis_domain, nis_map, user_name,
653                                         strlen(user_name), &nis_result,
654                                         &nis_result_len)) == 0) {
655                 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
656                         nis_result[nis_result_len] = '\0';
657                 }
658                 value = talloc_strdup(ctx, nis_result);
659                 if (!value) {
660                         return NULL;
661                 }
662                 value = strip_mount_options(ctx, value);
663         } else if(nis_error == YPERR_KEY) {
664                 DEBUG(3, ("YP Key not found:  while looking up \"%s\" in map \"%s\"\n", 
665                                 user_name, nis_map));
666                 DEBUG(3, ("using defaults for server and home directory\n"));
667         } else {
668                 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", 
669                                 yperr_string(nis_error), user_name, nis_map));
670         }
671
672         if (value) {
673                 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
674         }
675         return value;
676 }
677 #endif /* WITH_NISPLUS_HOME */
678 #endif
679
680 /****************************************************************************
681  Check if a process exists. Does this work on all unixes?
682 ****************************************************************************/
683
684 bool process_exists(const struct server_id pid)
685 {
686         if (procid_is_me(&pid)) {
687                 return True;
688         }
689
690         if (procid_is_local(&pid)) {
691                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
692         }
693
694 #ifdef CLUSTER_SUPPORT
695         return ctdbd_process_exists(messaging_ctdbd_connection(),
696                                     pid.vnn, pid.pid);
697 #else
698         return False;
699 #endif
700 }
701
702 bool processes_exist(const struct server_id *pids, int num_pids,
703                      bool *results)
704 {
705         struct server_id *remote_pids = NULL;
706         int *remote_idx = NULL;
707         bool *remote_results = NULL;
708         int i, num_remote_pids;
709         bool result = false;
710
711         remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
712         if (remote_pids == NULL) {
713                 goto fail;
714         }
715         remote_idx = talloc_array(talloc_tos(), int, num_pids);
716         if (remote_idx == NULL) {
717                 goto fail;
718         }
719         remote_results = talloc_array(talloc_tos(), bool, num_pids);
720         if (remote_results == NULL) {
721                 goto fail;
722         }
723
724         num_remote_pids = 0;
725
726         for (i=0; i<num_pids; i++) {
727                 if (procid_is_me(&pids[i])) {
728                         results[i] = true;
729                         continue;
730                 }
731                 if (procid_is_local(&pids[i])) {
732                         results[i] = ((kill(pids[i].pid,0) == 0) ||
733                                       (errno != ESRCH));
734                         continue;
735                 }
736
737                 remote_pids[num_remote_pids] = pids[i];
738                 remote_idx[num_remote_pids] = i;
739                 num_remote_pids += 1;
740         }
741
742         if (num_remote_pids != 0) {
743 #ifdef CLUSTER_SUPPORT
744                 if (!ctdb_processes_exist(messaging_ctdbd_connection(),
745                                           remote_pids, num_remote_pids,
746                                           remote_results)) {
747                         goto fail;
748                 }
749 #else
750                 for (i=0; i<num_remote_pids; i++) {
751                         remote_results[i] = false;
752                 }
753 #endif
754
755                 for (i=0; i<num_remote_pids; i++) {
756                         results[remote_idx[i]] = remote_results[i];
757                 }
758         }
759
760         result = true;
761 fail:
762         TALLOC_FREE(remote_results);
763         TALLOC_FREE(remote_idx);
764         TALLOC_FREE(remote_pids);
765         return result;
766 }
767
768 /*******************************************************************
769  Convert a uid into a user name.
770 ********************************************************************/
771
772 const char *uidtoname(uid_t uid)
773 {
774         TALLOC_CTX *ctx = talloc_tos();
775         char *name = NULL;
776         struct passwd *pass = NULL;
777
778         pass = getpwuid_alloc(ctx,uid);
779         if (pass) {
780                 name = talloc_strdup(ctx,pass->pw_name);
781                 TALLOC_FREE(pass);
782         } else {
783                 name = talloc_asprintf(ctx,
784                                 "%ld",
785                                 (long int)uid);
786         }
787         return name;
788 }
789
790 /*******************************************************************
791  Convert a gid into a group name.
792 ********************************************************************/
793
794 char *gidtoname(gid_t gid)
795 {
796         struct group *grp;
797
798         grp = getgrgid(gid);
799         if (grp) {
800                 return talloc_strdup(talloc_tos(), grp->gr_name);
801         }
802         else {
803                 return talloc_asprintf(talloc_tos(),
804                                         "%d",
805                                         (int)gid);
806         }
807 }
808
809 /*******************************************************************
810  Convert a user name into a uid.
811 ********************************************************************/
812
813 uid_t nametouid(const char *name)
814 {
815         struct passwd *pass;
816         char *p;
817         uid_t u;
818
819         pass = Get_Pwnam_alloc(talloc_tos(), name);
820         if (pass) {
821                 u = pass->pw_uid;
822                 TALLOC_FREE(pass);
823                 return u;
824         }
825
826         u = (uid_t)strtol(name, &p, 0);
827         if ((p != name) && (*p == '\0'))
828                 return u;
829
830         return (uid_t)-1;
831 }
832
833 /*******************************************************************
834  Convert a name to a gid_t if possible. Return -1 if not a group. 
835 ********************************************************************/
836
837 gid_t nametogid(const char *name)
838 {
839         struct group *grp;
840         char *p;
841         gid_t g;
842
843         g = (gid_t)strtol(name, &p, 0);
844         if ((p != name) && (*p == '\0'))
845                 return g;
846
847         grp = getgrnam(name);
848         if (grp)
849                 return(grp->gr_gid);
850         return (gid_t)-1;
851 }
852
853 /*******************************************************************
854  Something really nasty happened - panic !
855 ********************************************************************/
856
857 void smb_panic_s3(const char *why)
858 {
859         char *cmd;
860         int result;
861
862         DEBUG(0,("PANIC (pid %llu): %s\n",
863                     (unsigned long long)sys_getpid(), why));
864         log_stack_trace();
865
866 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
867         /*
868          * Make sure all children can attach a debugger.
869          */
870         prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
871 #endif
872
873         cmd = lp_panic_action();
874         if (cmd && *cmd) {
875                 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
876                 result = system(cmd);
877
878                 if (result == -1)
879                         DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
880                                           strerror(errno)));
881                 else
882                         DEBUG(0, ("smb_panic(): action returned status %d\n",
883                                           WEXITSTATUS(result)));
884         }
885
886         dump_core();
887 }
888
889 /*******************************************************************
890  Print a backtrace of the stack to the debug log. This function
891  DELIBERATELY LEAKS MEMORY. The expectation is that you should
892  exit shortly after calling it.
893 ********************************************************************/
894
895 #ifdef HAVE_LIBUNWIND_H
896 #include <libunwind.h>
897 #endif
898
899 #ifdef HAVE_EXECINFO_H
900 #include <execinfo.h>
901 #endif
902
903 #ifdef HAVE_LIBEXC_H
904 #include <libexc.h>
905 #endif
906
907 void log_stack_trace(void)
908 {
909 #ifdef HAVE_LIBUNWIND
910         /* Try to use libunwind before any other technique since on ia64
911          * libunwind correctly walks the stack in more circumstances than
912          * backtrace.
913          */ 
914         unw_cursor_t cursor;
915         unw_context_t uc;
916         unsigned i = 0;
917
918         char procname[256];
919         unw_word_t ip, sp, off;
920
921         procname[sizeof(procname) - 1] = '\0';
922
923         if (unw_getcontext(&uc) != 0) {
924                 goto libunwind_failed;
925         }
926
927         if (unw_init_local(&cursor, &uc) != 0) {
928                 goto libunwind_failed;
929         }
930
931         DEBUG(0, ("BACKTRACE:\n"));
932
933         do {
934             ip = sp = 0;
935             unw_get_reg(&cursor, UNW_REG_IP, &ip);
936             unw_get_reg(&cursor, UNW_REG_SP, &sp);
937
938             switch (unw_get_proc_name(&cursor,
939                         procname, sizeof(procname) - 1, &off) ) {
940             case 0:
941                     /* Name found. */
942             case -UNW_ENOMEM:
943                     /* Name truncated. */
944                     DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
945                             i, procname, (long long)off,
946                             (long long)ip, (long long) sp));
947                     break;
948             default:
949             /* case -UNW_ENOINFO: */
950             /* case -UNW_EUNSPEC: */
951                     /* No symbol name found. */
952                     DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
953                             i, "<unknown symbol>",
954                             (long long)ip, (long long) sp));
955             }
956             ++i;
957         } while (unw_step(&cursor) > 0);
958
959         return;
960
961 libunwind_failed:
962         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
963
964 #elif HAVE_BACKTRACE_SYMBOLS
965         void *backtrace_stack[BACKTRACE_STACK_SIZE];
966         size_t backtrace_size;
967         char **backtrace_strings;
968
969         /* get the backtrace (stack frames) */
970         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
971         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
972
973         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
974                   (unsigned long)backtrace_size));
975
976         if (backtrace_strings) {
977                 int i;
978
979                 for (i = 0; i < backtrace_size; i++)
980                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
981
982                 /* Leak the backtrace_strings, rather than risk what free() might do */
983         }
984
985 #elif HAVE_LIBEXC
986
987         /* The IRIX libexc library provides an API for unwinding the stack. See
988          * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
989          * since we are about to abort anyway, it hardly matters.
990          */
991
992 #define NAMESIZE 32 /* Arbitrary */
993
994         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
995         char *          names[BACKTRACE_STACK_SIZE];
996         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
997
998         int             i;
999         int             levels;
1000
1001         ZERO_ARRAY(addrs);
1002         ZERO_ARRAY(names);
1003         ZERO_ARRAY(namebuf);
1004
1005         /* We need to be root so we can open our /proc entry to walk
1006          * our stack. It also helps when we want to dump core.
1007          */
1008         become_root();
1009
1010         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1011                 names[i] = namebuf + (i * NAMESIZE);
1012         }
1013
1014         levels = trace_back_stack(0, addrs, names,
1015                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1016
1017         DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1018         for (i = 0; i < levels; i++) {
1019                 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1020         }
1021 #undef NAMESIZE
1022
1023 #else
1024         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1025 #endif
1026 }
1027
1028 /*******************************************************************
1029   A readdir wrapper which just returns the file name.
1030  ********************************************************************/
1031
1032 const char *readdirname(SMB_STRUCT_DIR *p)
1033 {
1034         SMB_STRUCT_DIRENT *ptr;
1035         char *dname;
1036
1037         if (!p)
1038                 return(NULL);
1039
1040         ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1041         if (!ptr)
1042                 return(NULL);
1043
1044         dname = ptr->d_name;
1045
1046 #ifdef NEXT2
1047         if (telldir(p) < 0)
1048                 return(NULL);
1049 #endif
1050
1051 #ifdef HAVE_BROKEN_READDIR_NAME
1052         /* using /usr/ucb/cc is BAD */
1053         dname = dname - 2;
1054 #endif
1055
1056         return talloc_strdup(talloc_tos(), dname);
1057 }
1058
1059 /*******************************************************************
1060  Utility function used to decide if the last component 
1061  of a path matches a (possibly wildcarded) entry in a namelist.
1062 ********************************************************************/
1063
1064 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1065 {
1066         const char *last_component;
1067
1068         /* if we have no list it's obviously not in the path */
1069         if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1070                 return False;
1071         }
1072
1073         DEBUG(8, ("is_in_path: %s\n", name));
1074
1075         /* Get the last component of the unix name. */
1076         last_component = strrchr_m(name, '/');
1077         if (!last_component) {
1078                 last_component = name;
1079         } else {
1080                 last_component++; /* Go past '/' */
1081         }
1082
1083         for(; namelist->name != NULL; namelist++) {
1084                 if(namelist->is_wild) {
1085                         if (mask_match(last_component, namelist->name, case_sensitive)) {
1086                                 DEBUG(8,("is_in_path: mask match succeeded\n"));
1087                                 return True;
1088                         }
1089                 } else {
1090                         if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1091                                                 (!case_sensitive && (strcasecmp_m(last_component, namelist->name) == 0))) {
1092                                 DEBUG(8,("is_in_path: match succeeded\n"));
1093                                 return True;
1094                         }
1095                 }
1096         }
1097         DEBUG(8,("is_in_path: match not found\n"));
1098         return False;
1099 }
1100
1101 /*******************************************************************
1102  Strip a '/' separated list into an array of 
1103  name_compare_enties structures suitable for 
1104  passing to is_in_path(). We do this for
1105  speed so we can pre-parse all the names in the list 
1106  and don't do it for each call to is_in_path().
1107  We also check if the entry contains a wildcard to
1108  remove a potentially expensive call to mask_match
1109  if possible.
1110 ********************************************************************/
1111
1112 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1113 {
1114         char *name_end;
1115         char *namelist;
1116         char *nameptr;
1117         int num_entries = 0;
1118         int i;
1119
1120         (*ppname_array) = NULL;
1121
1122         if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0'))) 
1123                 return;
1124
1125         namelist = talloc_strdup(talloc_tos(), namelist_in);
1126         if (namelist == NULL) {
1127                 DEBUG(0,("set_namearray: talloc fail\n"));
1128                 return;
1129         }
1130         nameptr = namelist;
1131
1132         /* We need to make two passes over the string. The
1133                 first to count the number of elements, the second
1134                 to split it.
1135         */
1136
1137         while(*nameptr) {
1138                 if ( *nameptr == '/' ) {
1139                         /* cope with multiple (useless) /s) */
1140                         nameptr++;
1141                         continue;
1142                 }
1143                 /* anything left? */
1144                 if ( *nameptr == '\0' )
1145                         break;
1146
1147                 /* find the next '/' or consume remaining */
1148                 name_end = strchr_m(nameptr, '/');
1149                 if (name_end == NULL)
1150                         name_end = (char *)nameptr + strlen(nameptr);
1151
1152                 /* next segment please */
1153                 nameptr = name_end + 1;
1154                 num_entries++;
1155         }
1156
1157         if(num_entries == 0) {
1158                 talloc_free(namelist);
1159                 return;
1160         }
1161
1162         if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1163                 DEBUG(0,("set_namearray: malloc fail\n"));
1164                 talloc_free(namelist);
1165                 return;
1166         }
1167
1168         /* Now copy out the names */
1169         nameptr = namelist;
1170         i = 0;
1171         while(*nameptr) {
1172                 if ( *nameptr == '/' ) {
1173                         /* cope with multiple (useless) /s) */
1174                         nameptr++;
1175                         continue;
1176                 }
1177                 /* anything left? */
1178                 if ( *nameptr == '\0' )
1179                         break;
1180
1181                 /* find the next '/' or consume remaining */
1182                 name_end = strchr_m(nameptr, '/');
1183                 if (name_end)
1184                         *name_end = '\0';
1185                 else
1186                         name_end = nameptr + strlen(nameptr);
1187
1188                 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1189                 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1190                         DEBUG(0,("set_namearray: malloc fail (1)\n"));
1191                         talloc_free(namelist);
1192                         return;
1193                 }
1194
1195                 /* next segment please */
1196                 nameptr = name_end + 1;
1197                 i++;
1198         }
1199
1200         (*ppname_array)[i].name = NULL;
1201
1202         talloc_free(namelist);
1203         return;
1204 }
1205
1206 #undef DBGC_CLASS
1207 #define DBGC_CLASS DBGC_LOCKING
1208
1209 /****************************************************************************
1210  Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1211  is dealt with in posix.c
1212  Returns True if we have information regarding this lock region (and returns
1213  F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1214 ****************************************************************************/
1215
1216 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1217 {
1218         SMB_STRUCT_FLOCK lock;
1219         int ret;
1220
1221         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1222                     fd,(double)*poffset,(double)*pcount,*ptype));
1223
1224         lock.l_type = *ptype;
1225         lock.l_whence = SEEK_SET;
1226         lock.l_start = *poffset;
1227         lock.l_len = *pcount;
1228         lock.l_pid = 0;
1229
1230         ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1231
1232         if (ret == -1) {
1233                 int sav = errno;
1234                 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1235                         (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1236                 errno = sav;
1237                 return False;
1238         }
1239
1240         *ptype = lock.l_type;
1241         *poffset = lock.l_start;
1242         *pcount = lock.l_len;
1243         *ppid = lock.l_pid;
1244
1245         DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1246                         fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1247         return True;
1248 }
1249
1250 #undef DBGC_CLASS
1251 #define DBGC_CLASS DBGC_ALL
1252
1253 /*******************************************************************
1254  Is the name specified one of my netbios names.
1255  Returns true if it is equal, false otherwise.
1256 ********************************************************************/
1257
1258 bool is_myname(const char *s)
1259 {
1260         int n;
1261         bool ret = False;
1262
1263         for (n=0; my_netbios_names(n); n++) {
1264                 if (strequal(my_netbios_names(n), s)) {
1265                         ret=True;
1266                         break;
1267                 }
1268         }
1269         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1270         return(ret);
1271 }
1272
1273 /*******************************************************************
1274  we distinguish between 2K and XP by the "Native Lan Manager" string
1275    WinXP => "Windows 2002 5.1"
1276    WinXP 64bit => "Windows XP 5.2"
1277    Win2k => "Windows 2000 5.0"
1278    NT4   => "Windows NT 4.0"
1279    Win9x => "Windows 4.0"
1280  Windows 2003 doesn't set the native lan manager string but
1281  they do set the domain to "Windows 2003 5.2" (probably a bug).
1282 ********************************************************************/
1283
1284 void ra_lanman_string( const char *native_lanman )
1285 {
1286         if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1287                 set_remote_arch( RA_WINXP );
1288         else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1289                 set_remote_arch( RA_WINXP64 );
1290         else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1291                 set_remote_arch( RA_WIN2K3 );
1292 }
1293
1294 static const char *remote_arch_str;
1295
1296 const char *get_remote_arch_str(void)
1297 {
1298         if (!remote_arch_str) {
1299                 return "UNKNOWN";
1300         }
1301         return remote_arch_str;
1302 }
1303
1304 /*******************************************************************
1305  Set the horrid remote_arch string based on an enum.
1306 ********************************************************************/
1307
1308 void set_remote_arch(enum remote_arch_types type)
1309 {
1310         ra_type = type;
1311         switch( type ) {
1312         case RA_WFWG:
1313                 remote_arch_str = "WfWg";
1314                 break;
1315         case RA_OS2:
1316                 remote_arch_str = "OS2";
1317                 break;
1318         case RA_WIN95:
1319                 remote_arch_str = "Win95";
1320                 break;
1321         case RA_WINNT:
1322                 remote_arch_str = "WinNT";
1323                 break;
1324         case RA_WIN2K:
1325                 remote_arch_str = "Win2K";
1326                 break;
1327         case RA_WINXP:
1328                 remote_arch_str = "WinXP";
1329                 break;
1330         case RA_WINXP64:
1331                 remote_arch_str = "WinXP64";
1332                 break;
1333         case RA_WIN2K3:
1334                 remote_arch_str = "Win2K3";
1335                 break;
1336         case RA_VISTA:
1337                 remote_arch_str = "Vista";
1338                 break;
1339         case RA_SAMBA:
1340                 remote_arch_str = "Samba";
1341                 break;
1342         case RA_CIFSFS:
1343                 remote_arch_str = "CIFSFS";
1344                 break;
1345         case RA_OSX:
1346                 remote_arch_str = "OSX";
1347                 break;
1348         default:
1349                 ra_type = RA_UNKNOWN;
1350                 remote_arch_str = "UNKNOWN";
1351                 break;
1352         }
1353
1354         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1355                                 remote_arch_str));
1356 }
1357
1358 /*******************************************************************
1359  Get the remote_arch type.
1360 ********************************************************************/
1361
1362 enum remote_arch_types get_remote_arch(void)
1363 {
1364         return ra_type;
1365 }
1366
1367 const char *tab_depth(int level, int depth)
1368 {
1369         if( CHECK_DEBUGLVL(level) ) {
1370                 dbgtext("%*s", depth*4, "");
1371         }
1372         return "";
1373 }
1374
1375 /*****************************************************************************
1376  Provide a checksum on a string
1377
1378  Input:  s - the null-terminated character string for which the checksum
1379              will be calculated.
1380
1381   Output: The checksum value calculated for s.
1382 *****************************************************************************/
1383
1384 int str_checksum(const char *s)
1385 {
1386         if (s == NULL)
1387                 return 0;
1388         return hash(s, strlen(s), 0);
1389 }
1390
1391 /*****************************************************************
1392  Zero a memory area then free it. Used to catch bugs faster.
1393 *****************************************************************/  
1394
1395 void zero_free(void *p, size_t size)
1396 {
1397         memset(p, 0, size);
1398         SAFE_FREE(p);
1399 }
1400
1401 /*****************************************************************
1402  Set our open file limit to a requested max and return the limit.
1403 *****************************************************************/  
1404
1405 int set_maxfiles(int requested_max)
1406 {
1407 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1408         struct rlimit rlp;
1409         int saved_current_limit;
1410
1411         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1412                 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1413                         strerror(errno) ));
1414                 /* just guess... */
1415                 return requested_max;
1416         }
1417
1418         /* 
1419          * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1420          * account for the extra fd we need 
1421          * as well as the log files and standard
1422          * handles etc. Save the limit we want to set in case
1423          * we are running on an OS that doesn't support this limit (AIX)
1424          * which always returns RLIM_INFINITY for rlp.rlim_max.
1425          */
1426
1427         /* Try raising the hard (max) limit to the requested amount. */
1428
1429 #if defined(RLIM_INFINITY)
1430         if (rlp.rlim_max != RLIM_INFINITY) {
1431                 int orig_max = rlp.rlim_max;
1432
1433                 if ( rlp.rlim_max < requested_max )
1434                         rlp.rlim_max = requested_max;
1435
1436                 /* This failing is not an error - many systems (Linux) don't
1437                         support our default request of 10,000 open files. JRA. */
1438
1439                 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1440                         DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n", 
1441                                 (int)rlp.rlim_max, strerror(errno) ));
1442
1443                         /* Set failed - restore original value from get. */
1444                         rlp.rlim_max = orig_max;
1445                 }
1446         }
1447 #endif
1448
1449         /* Now try setting the soft (current) limit. */
1450
1451         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1452
1453         if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1454                 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n", 
1455                         (int)rlp.rlim_cur, strerror(errno) ));
1456                 /* just guess... */
1457                 return saved_current_limit;
1458         }
1459
1460         if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1461                 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1462                         strerror(errno) ));
1463                 /* just guess... */
1464                 return saved_current_limit;
1465     }
1466
1467 #if defined(RLIM_INFINITY)
1468         if(rlp.rlim_cur == RLIM_INFINITY)
1469                 return saved_current_limit;
1470 #endif
1471
1472         if((int)rlp.rlim_cur > saved_current_limit)
1473                 return saved_current_limit;
1474
1475         return rlp.rlim_cur;
1476 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1477         /*
1478          * No way to know - just guess...
1479          */
1480         return requested_max;
1481 #endif
1482 }
1483
1484 /*****************************************************************
1485  malloc that aborts with smb_panic on fail or zero size.
1486  *****************************************************************/  
1487
1488 void *smb_xmalloc_array(size_t size, unsigned int count)
1489 {
1490         void *p;
1491         if (size == 0) {
1492                 smb_panic("smb_xmalloc_array: called with zero size");
1493         }
1494         if (count >= MAX_ALLOC_SIZE/size) {
1495                 smb_panic("smb_xmalloc_array: alloc size too large");
1496         }
1497         if ((p = SMB_MALLOC(size*count)) == NULL) {
1498                 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1499                         (unsigned long)size, (unsigned long)count));
1500                 smb_panic("smb_xmalloc_array: malloc failed");
1501         }
1502         return p;
1503 }
1504
1505 /*
1506   vasprintf that aborts on malloc fail
1507 */
1508
1509  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1510 {
1511         int n;
1512         va_list ap2;
1513
1514         va_copy(ap2, ap);
1515
1516         n = vasprintf(ptr, format, ap2);
1517         va_end(ap2);
1518         if (n == -1 || ! *ptr) {
1519                 smb_panic("smb_xvasprintf: out of memory");
1520         }
1521         return n;
1522 }
1523
1524 /*****************************************************************
1525  Get local hostname and cache result.
1526 *****************************************************************/
1527
1528 char *myhostname(void)
1529 {
1530         static char *ret;
1531         if (ret == NULL) {
1532                 ret = get_myname(NULL);
1533         }
1534         return ret;
1535 }
1536
1537 /*****************************************************************
1538  Get local hostname and cache result.
1539 *****************************************************************/
1540
1541 char *myhostname_upper(void)
1542 {
1543         char *name;
1544         static char *ret;
1545         if (ret == NULL) {
1546                 name = get_myname(talloc_tos());
1547                 ret = strupper_talloc(NULL, name);
1548                 talloc_free(name);
1549         }
1550         return ret;
1551 }
1552
1553 /**
1554  * @brief Returns an absolute path to a file concatenating the provided
1555  * @a rootpath and @a basename
1556  *
1557  * @param name Filename, relative to @a rootpath
1558  *
1559  * @retval Pointer to a string containing the full path.
1560  **/
1561
1562 static char *xx_path(const char *name, const char *rootpath)
1563 {
1564         char *fname = NULL;
1565
1566         fname = talloc_strdup(talloc_tos(), rootpath);
1567         if (!fname) {
1568                 return NULL;
1569         }
1570         trim_string(fname,"","/");
1571
1572         if (!directory_exist(fname)) {
1573                 if (!mkdir(fname,0755))
1574                         DEBUG(1, ("Unable to create directory %s for file %s. "
1575                               "Error was %s\n", fname, name, strerror(errno)));
1576         }
1577
1578         return talloc_asprintf(talloc_tos(),
1579                                 "%s/%s",
1580                                 fname,
1581                                 name);
1582 }
1583
1584 /**
1585  * @brief Returns an absolute path to a file in the Samba lock directory.
1586  *
1587  * @param name File to find, relative to LOCKDIR.
1588  *
1589  * @retval Pointer to a talloc'ed string containing the full path.
1590  **/
1591
1592 char *lock_path(const char *name)
1593 {
1594         return xx_path(name, lp_lockdir());
1595 }
1596
1597 /**
1598  * @brief Returns an absolute path to a file in the Samba state directory.
1599  *
1600  * @param name File to find, relative to STATEDIR.
1601  *
1602  * @retval Pointer to a talloc'ed string containing the full path.
1603  **/
1604
1605 char *state_path(const char *name)
1606 {
1607         return xx_path(name, lp_statedir());
1608 }
1609
1610 /**
1611  * @brief Returns an absolute path to a file in the Samba cache directory.
1612  *
1613  * @param name File to find, relative to CACHEDIR.
1614  *
1615  * @retval Pointer to a talloc'ed string containing the full path.
1616  **/
1617
1618 char *cache_path(const char *name)
1619 {
1620         return xx_path(name, lp_cachedir());
1621 }
1622
1623 /*******************************************************************
1624  Given a filename - get its directory name
1625 ********************************************************************/
1626
1627 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1628                     const char **name)
1629 {
1630         char *p;
1631         ptrdiff_t len;
1632
1633         p = strrchr_m(dir, '/'); /* Find final '/', if any */
1634
1635         if (p == NULL) {
1636                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1637                         return False;
1638                 }
1639                 if (name) {
1640                         *name = dir;
1641                 }
1642                 return True;
1643         }
1644
1645         len = p-dir;
1646
1647         if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1648                 return False;
1649         }
1650         (*parent)[len] = '\0';
1651
1652         if (name) {
1653                 *name = p+1;
1654         }
1655         return True;
1656 }
1657
1658 /*******************************************************************
1659  Determine if a pattern contains any Microsoft wildcard characters.
1660 *******************************************************************/
1661
1662 bool ms_has_wild(const char *s)
1663 {
1664         char c;
1665
1666         if (lp_posix_pathnames()) {
1667                 /* With posix pathnames no characters are wild. */
1668                 return False;
1669         }
1670
1671         while ((c = *s++)) {
1672                 switch (c) {
1673                 case '*':
1674                 case '?':
1675                 case '<':
1676                 case '>':
1677                 case '"':
1678                         return True;
1679                 }
1680         }
1681         return False;
1682 }
1683
1684 bool ms_has_wild_w(const smb_ucs2_t *s)
1685 {
1686         smb_ucs2_t c;
1687         if (!s) return False;
1688         while ((c = *s++)) {
1689                 switch (c) {
1690                 case UCS2_CHAR('*'):
1691                 case UCS2_CHAR('?'):
1692                 case UCS2_CHAR('<'):
1693                 case UCS2_CHAR('>'):
1694                 case UCS2_CHAR('"'):
1695                         return True;
1696                 }
1697         }
1698         return False;
1699 }
1700
1701 /*******************************************************************
1702  A wrapper that handles case sensitivity and the special handling
1703  of the ".." name.
1704 *******************************************************************/
1705
1706 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1707 {
1708         if (ISDOTDOT(string))
1709                 string = ".";
1710         if (ISDOT(pattern))
1711                 return False;
1712
1713         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1714 }
1715
1716 /*******************************************************************
1717  A wrapper that handles case sensitivity and the special handling
1718  of the ".." name. Varient that is only called by old search code which requires
1719  pattern translation.
1720 *******************************************************************/
1721
1722 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1723 {
1724         if (ISDOTDOT(string))
1725                 string = ".";
1726         if (ISDOT(pattern))
1727                 return False;
1728
1729         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1730 }
1731
1732 /*******************************************************************
1733  A wrapper that handles a list of patters and calls mask_match()
1734  on each.  Returns True if any of the patterns match.
1735 *******************************************************************/
1736
1737 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1738 {
1739        while (listLen-- > 0) {
1740                if (mask_match(string, *list++, is_case_sensitive))
1741                        return True;
1742        }
1743        return False;
1744 }
1745
1746 /*********************************************************
1747  Recursive routine that is called by unix_wild_match.
1748 *********************************************************/
1749
1750 static bool unix_do_match(const char *regexp, const char *str)
1751 {
1752         const char *p;
1753
1754         for( p = regexp; *p && *str; ) {
1755
1756                 switch(*p) {
1757                         case '?':
1758                                 str++;
1759                                 p++;
1760                                 break;
1761
1762                         case '*':
1763
1764                                 /*
1765                                  * Look for a character matching 
1766                                  * the one after the '*'.
1767                                  */
1768                                 p++;
1769                                 if(!*p)
1770                                         return true; /* Automatic match */
1771                                 while(*str) {
1772
1773                                         while(*str && (*p != *str))
1774                                                 str++;
1775
1776                                         /*
1777                                          * Patch from weidel@multichart.de. In the case of the regexp
1778                                          * '*XX*' we want to ensure there are at least 2 'X' characters
1779                                          * in the string after the '*' for a match to be made.
1780                                          */
1781
1782                                         {
1783                                                 int matchcount=0;
1784
1785                                                 /*
1786                                                  * Eat all the characters that match, but count how many there were.
1787                                                  */
1788
1789                                                 while(*str && (*p == *str)) {
1790                                                         str++;
1791                                                         matchcount++;
1792                                                 }
1793
1794                                                 /*
1795                                                  * Now check that if the regexp had n identical characters that
1796                                                  * matchcount had at least that many matches.
1797                                                  */
1798
1799                                                 while ( *(p+1) && (*(p+1) == *p)) {
1800                                                         p++;
1801                                                         matchcount--;
1802                                                 }
1803
1804                                                 if ( matchcount <= 0 )
1805                                                         return false;
1806                                         }
1807
1808                                         str--; /* We've eaten the match char after the '*' */
1809
1810                                         if(unix_do_match(p, str))
1811                                                 return true;
1812
1813                                         if(!*str)
1814                                                 return false;
1815                                         else
1816                                                 str++;
1817                                 }
1818                                 return false;
1819
1820                         default:
1821                                 if(*str != *p)
1822                                         return false;
1823                                 str++;
1824                                 p++;
1825                                 break;
1826                 }
1827         }
1828
1829         if(!*p && !*str)
1830                 return true;
1831
1832         if (!*p && str[0] == '.' && str[1] == 0)
1833                 return true;
1834
1835         if (!*str && *p == '?') {
1836                 while (*p == '?')
1837                         p++;
1838                 return(!*p);
1839         }
1840
1841         if(!*str && (*p == '*' && p[1] == '\0'))
1842                 return true;
1843
1844         return false;
1845 }
1846
1847 /*******************************************************************
1848  Simple case insensitive interface to a UNIX wildcard matcher.
1849  Returns True if match, False if not.
1850 *******************************************************************/
1851
1852 bool unix_wild_match(const char *pattern, const char *string)
1853 {
1854         TALLOC_CTX *ctx = talloc_stackframe();
1855         char *p2;
1856         char *s2;
1857         char *p;
1858         bool ret = false;
1859
1860         p2 = talloc_strdup(ctx,pattern);
1861         s2 = talloc_strdup(ctx,string);
1862         if (!p2 || !s2) {
1863                 TALLOC_FREE(ctx);
1864                 return false;
1865         }
1866         strlower_m(p2);
1867         strlower_m(s2);
1868
1869         /* Remove any *? and ** from the pattern as they are meaningless */
1870         for(p = p2; *p; p++) {
1871                 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1872                         memmove(&p[1], &p[2], strlen(&p[2])+1);
1873                 }
1874         }
1875
1876         if (strequal(p2,"*")) {
1877                 TALLOC_FREE(ctx);
1878                 return true;
1879         }
1880
1881         ret = unix_do_match(p2, s2);
1882         TALLOC_FREE(ctx);
1883         return ret;
1884 }
1885
1886 /**********************************************************************
1887  Converts a name to a fully qualified domain name.
1888  Returns true if lookup succeeded, false if not (then fqdn is set to name)
1889  Note we deliberately use gethostbyname here, not getaddrinfo as we want
1890  to examine the h_aliases and I don't know how to do that with getaddrinfo.
1891 ***********************************************************************/
1892
1893 bool name_to_fqdn(fstring fqdn, const char *name)
1894 {
1895         char *full = NULL;
1896         struct hostent *hp = gethostbyname(name);
1897
1898         if (!hp || !hp->h_name || !*hp->h_name) {
1899                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1900                 fstrcpy(fqdn, name);
1901                 return false;
1902         }
1903
1904         /* Find out if the fqdn is returned as an alias
1905          * to cope with /etc/hosts files where the first
1906          * name is not the fqdn but the short name */
1907         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1908                 int i;
1909                 for (i = 0; hp->h_aliases[i]; i++) {
1910                         if (strchr_m(hp->h_aliases[i], '.')) {
1911                                 full = hp->h_aliases[i];
1912                                 break;
1913                         }
1914                 }
1915         }
1916         if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1917                 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1918                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1919                 DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
1920                 DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
1921                 full = hp->h_name;
1922         }
1923         if (!full) {
1924                 full = hp->h_name;
1925         }
1926
1927         DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1928         fstrcpy(fqdn, full);
1929         return true;
1930 }
1931
1932 /**********************************************************************
1933  Append a DATA_BLOB to a talloc'ed object
1934 ***********************************************************************/
1935
1936 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1937 {
1938         size_t old_size = 0;
1939         char *result;
1940
1941         if (blob.length == 0) {
1942                 return buf;
1943         }
1944
1945         if (buf != NULL) {
1946                 old_size = talloc_get_size(buf);
1947         }
1948
1949         result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1950         if (result == NULL) {
1951                 return NULL;
1952         }
1953
1954         memcpy(result + old_size, blob.data, blob.length);
1955         return result;
1956 }
1957
1958 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1959 {
1960         switch (share_access & ~FILE_SHARE_DELETE) {
1961                 case FILE_SHARE_NONE:
1962                         return DENY_ALL;
1963                 case FILE_SHARE_READ:
1964                         return DENY_WRITE;
1965                 case FILE_SHARE_WRITE:
1966                         return DENY_READ;
1967                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
1968                         return DENY_NONE;
1969         }
1970         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
1971                 return DENY_DOS;
1972         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
1973                 return DENY_FCB;
1974         }
1975
1976         return (uint32)-1;
1977 }
1978
1979 pid_t procid_to_pid(const struct server_id *proc)
1980 {
1981         return proc->pid;
1982 }
1983
1984 static uint32 my_vnn = NONCLUSTER_VNN;
1985
1986 void set_my_vnn(uint32 vnn)
1987 {
1988         DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
1989         my_vnn = vnn;
1990 }
1991
1992 uint32 get_my_vnn(void)
1993 {
1994         return my_vnn;
1995 }
1996
1997 static uint64_t my_unique_id = 0;
1998
1999 void set_my_unique_id(uint64_t unique_id)
2000 {
2001         my_unique_id = unique_id;
2002 }
2003
2004 struct server_id pid_to_procid(pid_t pid)
2005 {
2006         struct server_id result;
2007         result.pid = pid;
2008         result.task_id = 0;
2009         result.unique_id = my_unique_id;
2010         result.vnn = my_vnn;
2011         return result;
2012 }
2013
2014 struct server_id procid_self(void)
2015 {
2016         return pid_to_procid(sys_getpid());
2017 }
2018
2019 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2020 {
2021         if (p1->pid != p2->pid)
2022                 return False;
2023         if (p1->task_id != p2->task_id)
2024                 return False;
2025         if (p1->vnn != p2->vnn)
2026                 return False;
2027         return True;
2028 }
2029
2030 bool cluster_id_equal(const struct server_id *id1,
2031                       const struct server_id *id2)
2032 {
2033         return procid_equal(id1, id2);
2034 }
2035
2036 bool procid_is_me(const struct server_id *pid)
2037 {
2038         if (pid->pid != sys_getpid())
2039                 return False;
2040         if (pid->task_id != 0)
2041                 return False;
2042         if (pid->vnn != my_vnn)
2043                 return False;
2044         return True;
2045 }
2046
2047 struct server_id interpret_pid(const char *pid_string)
2048 {
2049         struct server_id result;
2050         unsigned long long pid;
2051         unsigned int vnn, task_id = 0;
2052
2053         ZERO_STRUCT(result);
2054
2055         /* We accept various forms with 1, 2 or 3 component forms
2056          * because the server_id_str() can print different forms, and
2057          * we want backwards compatibility for scripts that may call
2058          * smbclient. */
2059         if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2060                 result.vnn = vnn;
2061                 result.pid = pid;
2062                 result.task_id = task_id;
2063         } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2064                 result.vnn = vnn;
2065                 result.pid = pid;
2066                 result.task_id = 0;
2067         } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2068                 result.vnn = get_my_vnn();
2069                 result.pid = pid;
2070                 result.task_id = task_id;
2071         } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2072                 result.vnn = get_my_vnn();
2073                 result.pid = pid;
2074         } else {
2075                 result.vnn = NONCLUSTER_VNN;
2076                 result.pid = (uint64_t)-1;
2077         }
2078         return result;
2079 }
2080
2081 char *procid_str_static(const struct server_id *pid)
2082 {
2083         return server_id_str(talloc_tos(), pid);
2084 }
2085
2086 bool procid_valid(const struct server_id *pid)
2087 {
2088         return (pid->pid != (uint64_t)-1);
2089 }
2090
2091 bool procid_is_local(const struct server_id *pid)
2092 {
2093         return pid->vnn == my_vnn;
2094 }
2095
2096 /****************************************************************
2097  Check if an offset into a buffer is safe.
2098  If this returns True it's safe to indirect into the byte at
2099  pointer ptr+off.
2100 ****************************************************************/
2101
2102 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2103 {
2104         const char *end_base = buf_base + buf_len;
2105         char *end_ptr = ptr + off;
2106
2107         if (!buf_base || !ptr) {
2108                 return False;
2109         }
2110
2111         if (end_base < buf_base || end_ptr < ptr) {
2112                 return False; /* wrap. */
2113         }
2114
2115         if (end_ptr < end_base) {
2116                 return True;
2117         }
2118         return False;
2119 }
2120
2121 /****************************************************************
2122  Return a safe pointer into a buffer, or NULL.
2123 ****************************************************************/
2124
2125 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2126 {
2127         return is_offset_safe(buf_base, buf_len, ptr, off) ?
2128                         ptr + off : NULL;
2129 }
2130
2131 /****************************************************************
2132  Return a safe pointer into a string within a buffer, or NULL.
2133 ****************************************************************/
2134
2135 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2136 {
2137         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2138                 return NULL;
2139         }
2140         /* Check if a valid string exists at this offset. */
2141         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2142                 return NULL;
2143         }
2144         return ptr + off;
2145 }
2146
2147 /****************************************************************
2148  Return an SVAL at a pointer, or failval if beyond the end.
2149 ****************************************************************/
2150
2151 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2152 {
2153         /*
2154          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2155          * NOT ptr[2].
2156          */
2157         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2158                 return failval;
2159         }
2160         return SVAL(ptr,off);
2161 }
2162
2163 /****************************************************************
2164  Return an IVAL at a pointer, or failval if beyond the end.
2165 ****************************************************************/
2166
2167 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2168 {
2169         /*
2170          * Note we use off+3 here, not off+4 as IVAL accesses 
2171          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2172          */
2173         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2174                 return failval;
2175         }
2176         return IVAL(ptr,off);
2177 }
2178
2179 /****************************************************************
2180  Split DOM\user into DOM and user. Do not mix with winbind variants of that
2181  call (they take care of winbind separator and other winbind specific settings).
2182 ****************************************************************/
2183
2184 void split_domain_user(TALLOC_CTX *mem_ctx,
2185                        const char *full_name,
2186                        char **domain,
2187                        char **user)
2188 {
2189         const char *p = NULL;
2190
2191         p = strchr_m(full_name, '\\');
2192
2193         if (p != NULL) {
2194                 *domain = talloc_strndup(mem_ctx, full_name,
2195                                          PTR_DIFF(p, full_name));
2196                 *user = talloc_strdup(mem_ctx, p+1);
2197         } else {
2198                 *domain = talloc_strdup(mem_ctx, "");
2199                 *user = talloc_strdup(mem_ctx, full_name);
2200         }
2201 }
2202
2203 /****************************************************************
2204  strip off leading '\\' from a hostname
2205 ****************************************************************/
2206
2207 const char *strip_hostname(const char *s)
2208 {
2209         if (!s) {
2210                 return NULL;
2211         }
2212
2213         if (strlen_m(s) < 3) {
2214                 return s;
2215         }
2216
2217         if (s[0] == '\\') s++;
2218         if (s[0] == '\\') s++;
2219
2220         return s;
2221 }
2222
2223 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2224                               struct tevent_context *ev,
2225                               NTSTATUS *status)
2226 {
2227         bool ret = tevent_req_poll(req, ev);
2228         if (!ret) {
2229                 *status = map_nt_error_from_unix(errno);
2230         }
2231         return ret;
2232 }
2233
2234 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2235 {
2236         if (!NT_STATUS_IS_OK(err1)) {
2237                 *result = err1;
2238                 return true;
2239         }
2240         if (!NT_STATUS_IS_OK(err2)) {
2241                 *result = err2;
2242                 return true;
2243         }
2244         return false;
2245 }
2246
2247 int timeval_to_msec(struct timeval t)
2248 {
2249         return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2250 }
2251
2252 /*******************************************************************
2253  Check a given DOS pathname is valid for a share.
2254 ********************************************************************/
2255
2256 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2257 {
2258         char *ptr = NULL;
2259
2260         if (!dos_pathname) {
2261                 return NULL;
2262         }
2263
2264         ptr = talloc_strdup(ctx, dos_pathname);
2265         if (!ptr) {
2266                 return NULL;
2267         }
2268         /* Convert any '\' paths to '/' */
2269         unix_format(ptr);
2270         ptr = unix_clean_name(ctx, ptr);
2271         if (!ptr) {
2272                 return NULL;
2273         }
2274
2275         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2276         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2277                 ptr += 2;
2278
2279         /* Only absolute paths allowed. */
2280         if (*ptr != '/')
2281                 return NULL;
2282
2283         return ptr;
2284 }
2285
2286 /*******************************************************************
2287  Return True if the filename is one of the special executable types.
2288 ********************************************************************/
2289
2290 bool is_executable(const char *fname)
2291 {
2292         if ((fname = strrchr_m(fname,'.'))) {
2293                 if (strequal(fname,".com") ||
2294                     strequal(fname,".dll") ||
2295                     strequal(fname,".exe") ||
2296                     strequal(fname,".sym")) {
2297                         return True;
2298                 }
2299         }
2300         return False;
2301 }
2302
2303 /****************************************************************************
2304  Open a file with a share mode - old openX method - map into NTCreate.
2305 ****************************************************************************/
2306
2307 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2308                                  int deny_mode, int open_func,
2309                                  uint32 *paccess_mask,
2310                                  uint32 *pshare_mode,
2311                                  uint32 *pcreate_disposition,
2312                                  uint32 *pcreate_options,
2313                                  uint32_t *pprivate_flags)
2314 {
2315         uint32 access_mask;
2316         uint32 share_mode;
2317         uint32 create_disposition;
2318         uint32 create_options = FILE_NON_DIRECTORY_FILE;
2319         uint32_t private_flags = 0;
2320
2321         DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2322                   "open_func = 0x%x\n",
2323                   smb_base_fname, (unsigned int)deny_mode,
2324                   (unsigned int)open_func ));
2325
2326         /* Create the NT compatible access_mask. */
2327         switch (GET_OPENX_MODE(deny_mode)) {
2328                 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2329                 case DOS_OPEN_RDONLY:
2330                         access_mask = FILE_GENERIC_READ;
2331                         break;
2332                 case DOS_OPEN_WRONLY:
2333                         access_mask = FILE_GENERIC_WRITE;
2334                         break;
2335                 case DOS_OPEN_RDWR:
2336                 case DOS_OPEN_FCB:
2337                         access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2338                         break;
2339                 default:
2340                         DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2341                                   (unsigned int)GET_OPENX_MODE(deny_mode)));
2342                         return False;
2343         }
2344
2345         /* Create the NT compatible create_disposition. */
2346         switch (open_func) {
2347                 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2348                         create_disposition = FILE_CREATE;
2349                         break;
2350
2351                 case OPENX_FILE_EXISTS_OPEN:
2352                         create_disposition = FILE_OPEN;
2353                         break;
2354
2355                 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2356                         create_disposition = FILE_OPEN_IF;
2357                         break;
2358
2359                 case OPENX_FILE_EXISTS_TRUNCATE:
2360                         create_disposition = FILE_OVERWRITE;
2361                         break;
2362
2363                 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2364                         create_disposition = FILE_OVERWRITE_IF;
2365                         break;
2366
2367                 default:
2368                         /* From samba4 - to be confirmed. */
2369                         if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2370                                 create_disposition = FILE_CREATE;
2371                                 break;
2372                         }
2373                         DEBUG(10,("map_open_params_to_ntcreate: bad "
2374                                   "open_func 0x%x\n", (unsigned int)open_func));
2375                         return False;
2376         }
2377
2378         /* Create the NT compatible share modes. */
2379         switch (GET_DENY_MODE(deny_mode)) {
2380                 case DENY_ALL:
2381                         share_mode = FILE_SHARE_NONE;
2382                         break;
2383
2384                 case DENY_WRITE:
2385                         share_mode = FILE_SHARE_READ;
2386                         break;
2387
2388                 case DENY_READ:
2389                         share_mode = FILE_SHARE_WRITE;
2390                         break;
2391
2392                 case DENY_NONE:
2393                         share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2394                         break;
2395
2396                 case DENY_DOS:
2397                         private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2398                         if (is_executable(smb_base_fname)) {
2399                                 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2400                         } else {
2401                                 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2402                                         share_mode = FILE_SHARE_READ;
2403                                 } else {
2404                                         share_mode = FILE_SHARE_NONE;
2405                                 }
2406                         }
2407                         break;
2408
2409                 case DENY_FCB:
2410                         private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2411                         share_mode = FILE_SHARE_NONE;
2412                         break;
2413
2414                 default:
2415                         DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2416                                 (unsigned int)GET_DENY_MODE(deny_mode) ));
2417                         return False;
2418         }
2419
2420         DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2421                   "share_mode = 0x%x, create_disposition = 0x%x, "
2422                   "create_options = 0x%x private_flags = 0x%x\n",
2423                   smb_base_fname,
2424                   (unsigned int)access_mask,
2425                   (unsigned int)share_mode,
2426                   (unsigned int)create_disposition,
2427                   (unsigned int)create_options,
2428                   (unsigned int)private_flags));
2429
2430         if (paccess_mask) {
2431                 *paccess_mask = access_mask;
2432         }
2433         if (pshare_mode) {
2434                 *pshare_mode = share_mode;
2435         }
2436         if (pcreate_disposition) {
2437                 *pcreate_disposition = create_disposition;
2438         }
2439         if (pcreate_options) {
2440                 *pcreate_options = create_options;
2441         }
2442         if (pprivate_flags) {
2443                 *pprivate_flags = private_flags;
2444         }
2445
2446         return True;
2447
2448 }
2449
2450
2451 void init_modules(void)
2452 {
2453         /* FIXME: This can cause undefined symbol errors :
2454          *  smb_register_vfs() isn't available in nmbd, for example */
2455         if(lp_preload_modules())
2456                 smb_load_modules(lp_preload_modules());
2457 }