Correctly check for errors in strlower_m() returns.
[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  Check two stats have identical dev and ino fields.
131 ****************************************************************************/
132
133 bool check_same_dev_ino(const SMB_STRUCT_STAT *sbuf1,
134                         const SMB_STRUCT_STAT *sbuf2)
135 {
136         if (sbuf1->st_ex_dev != sbuf2->st_ex_dev ||
137                         sbuf1->st_ex_ino != sbuf2->st_ex_ino) {
138                 return false;
139         }
140         return true;
141 }
142
143 /****************************************************************************
144  Check if a stat struct is identical for use.
145 ****************************************************************************/
146
147 bool check_same_stat(const SMB_STRUCT_STAT *sbuf1,
148                         const SMB_STRUCT_STAT *sbuf2)
149 {
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;
154         }
155         return true;
156 }
157
158 /*******************************************************************
159  Show a smb message structure.
160 ********************************************************************/
161
162 void show_msg(const char *buf)
163 {
164         int i;
165         int bcc=0;
166
167         if (!DEBUGLVL(5))
168                 return;
169
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)));
184
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)));
188
189         bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
190
191         DEBUGADD(5,("smb_bcc=%d\n",bcc));
192
193         if (DEBUGLEVEL < 10)
194                 return;
195
196         if (DEBUGLEVEL < 50)
197                 bcc = MIN(bcc, 512);
198
199         dump_data(10, (const uint8 *)smb_buf_const(buf), bcc);
200 }
201
202 /*******************************************************************
203  Setup only the byte count for a smb message.
204 ********************************************************************/
205
206 int set_message_bcc(char *buf,int num_bytes)
207 {
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);
212 }
213
214 /*******************************************************************
215  Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
216  Return the bytes added
217 ********************************************************************/
218
219 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
220 {
221         size_t newlen = smb_len(*outbuf) + 4 + blob.length;
222         uint8 *tmp;
223
224         if (!(tmp = talloc_realloc(NULL, *outbuf, uint8, newlen))) {
225                 DEBUG(0, ("talloc failed\n"));
226                 return -1;
227         }
228         *outbuf = tmp;
229
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;
233 }
234
235 /*******************************************************************
236  Reduce a file name, removing .. elements.
237 ********************************************************************/
238
239 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
240 {
241         char *p = NULL;
242         char *str = NULL;
243
244         DEBUG(3,("dos_clean_name [%s]\n",s));
245
246         /* remove any double slashes */
247         str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
248         if (!str) {
249                 return NULL;
250         }
251
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;
259                         }
260                 }
261         }
262
263         while ((p = strstr_m(str,"\\..\\")) != NULL) {
264                 char *s1;
265
266                 *p = 0;
267                 s1 = p+3;
268
269                 if ((p=strrchr_m(str,'\\')) != NULL) {
270                         *p = 0;
271                 } else {
272                         *str = 0;
273                 }
274                 str = talloc_asprintf(ctx,
275                                 "%s%s",
276                                 str,
277                                 s1);
278                 if (!str) {
279                         return NULL;
280                 }
281         }
282
283         trim_string(str,NULL,"\\..");
284         return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
285 }
286
287 /*******************************************************************
288  Reduce a file name, removing .. elements.
289 ********************************************************************/
290
291 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
292 {
293         char *p = NULL;
294         char *str = NULL;
295
296         DEBUG(3,("unix_clean_name [%s]\n",s));
297
298         /* remove any double slashes */
299         str = talloc_all_string_sub(ctx, s, "//","/");
300         if (!str) {
301                 return NULL;
302         }
303
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;
311                         }
312                 }
313         }
314
315         while ((p = strstr_m(str,"/../")) != NULL) {
316                 char *s1;
317
318                 *p = 0;
319                 s1 = p+3;
320
321                 if ((p=strrchr_m(str,'/')) != NULL) {
322                         *p = 0;
323                 } else {
324                         *str = 0;
325                 }
326                 str = talloc_asprintf(ctx,
327                                 "%s%s",
328                                 str,
329                                 s1);
330                 if (!str) {
331                         return NULL;
332                 }
333         }
334
335         trim_string(str,NULL,"/..");
336         return talloc_all_string_sub(ctx, str, "/./", "/");
337 }
338
339 char *clean_name(TALLOC_CTX *ctx, const char *s)
340 {
341         char *str = dos_clean_name(ctx, s);
342         if (!str) {
343                 return NULL;
344         }
345         return unix_clean_name(ctx, str);
346 }
347
348 /*******************************************************************
349  Write data into an fd at a given offset. Ignore seek errors.
350 ********************************************************************/
351
352 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, off_t pos)
353 {
354         size_t total=0;
355         ssize_t ret;
356
357         if (pos == (off_t)-1) {
358                 return write_data(fd, buffer, N);
359         }
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);
365                 }
366                 if (ret == -1) {
367                         DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
368                         return -1;
369                 }
370                 if (ret == 0) {
371                         return total;
372                 }
373                 total += ret;
374                 pos += ret;
375         }
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;
382                 }
383         }
384         return write_data(fd, buffer, N);
385 #endif
386 }
387
388 static int reinit_after_fork_pipe[2] = { -1, -1 };
389
390 NTSTATUS init_before_fork(void)
391 {
392         int ret;
393
394         ret = pipe(reinit_after_fork_pipe);
395         if (ret == -1) {
396                 NTSTATUS status;
397
398                 status = map_nt_error_from_unix_common(errno);
399
400                 DEBUG(0, ("Error creating child_pipe: %s\n",
401                           nt_errstr(status)));
402
403                 return status;
404         }
405
406         return NT_STATUS_OK;
407 }
408
409 /**
410  * Detect died parent by detecting EOF on the pipe
411  */
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)
416 {
417         char c;
418
419         if (sys_read(reinit_after_fork_pipe[0], &c, 1) != 1) {
420                 /*
421                  * we have reached EOF on stdin, which means the
422                  * parent has exited. Shutdown the server
423                  */
424                 (void)kill(getpid(), SIGTERM);
425         }
426 }
427
428
429 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
430                            struct event_context *ev_ctx,
431                            bool parent_longlived)
432 {
433         NTSTATUS status = NT_STATUS_OK;
434
435         if (reinit_after_fork_pipe[1] != -1) {
436                 close(reinit_after_fork_pipe[1]);
437                 reinit_after_fork_pipe[1] = -1;
438         }
439
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();
445
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;
451         }
452
453         if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
454                 smb_panic(__location__ ": Failed to re-initialise event context");
455         }
456
457         if (reinit_after_fork_pipe[0] != -1) {
458                 struct tevent_fd *fde;
459
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");
465                 }
466         }
467
468         if (msg_ctx) {
469                 /*
470                  * For clustering, we need to re-init our ctdbd connection after the
471                  * fork
472                  */
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)));
477                 }
478         }
479  done:
480         return status;
481 }
482
483 /****************************************************************************
484  (Hopefully) efficient array append.
485 ****************************************************************************/
486
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)
490 {
491         void **array = (void **)_array;
492
493         if (*array_size < 0) {
494                 return;
495         }
496
497         if (*array == NULL) {
498                 if (*array_size == 0) {
499                         *array_size = 128;
500                 }
501
502                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
503                         goto error;
504                 }
505
506                 *array = TALLOC(mem_ctx, element_size * (*array_size));
507                 if (*array == NULL) {
508                         goto error;
509                 }
510         }
511
512         if (*num_elements == *array_size) {
513                 *array_size *= 2;
514
515                 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
516                         goto error;
517                 }
518
519                 *array = TALLOC_REALLOC(mem_ctx, *array,
520                                         element_size * (*array_size));
521
522                 if (*array == NULL) {
523                         goto error;
524                 }
525         }
526
527         memcpy((char *)(*array) + element_size*(*num_elements),
528                element, element_size);
529         *num_elements += 1;
530
531         return;
532
533  error:
534         *num_elements = 0;
535         *array_size = -1;
536 }
537
538 /****************************************************************************
539  Get my own domain name, or "" if we have none.
540 ****************************************************************************/
541
542 char *get_mydnsdomname(TALLOC_CTX *ctx)
543 {
544         const char *domname;
545         char *p;
546
547         domname = get_mydnsfullname();
548         if (!domname) {
549                 return NULL;
550         }
551
552         p = strchr_m(domname, '.');
553         if (p) {
554                 p++;
555                 return talloc_strdup(ctx, p);
556         } else {
557                 return talloc_strdup(ctx, "");
558         }
559 }
560
561 /****************************************************************************
562  Interpret a protocol description string, with a default.
563 ****************************************************************************/
564
565 int interpret_protocol(const char *str,int def)
566 {
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);
579
580         DEBUG(0,("Unrecognised protocol level %s\n",str));
581
582         return(def);
583 }
584
585
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 *******************************************************************/
592
593 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
594 {
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);
603                 }
604         }
605         return NULL;
606 }
607
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 *******************************************************************/
614
615 #ifdef WITH_NISPLUS_HOME
616 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
617 {
618         char *value = NULL;
619
620         char *nis_map = (char *)lp_nis_home_map_name();
621
622         char buffer[NIS_MAXATTRVAL + 1];
623         nis_result *result;
624         nis_object *object;
625         entry_obj  *entry;
626
627         snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
628         DEBUG(5, ("NIS+ querystring: %s\n", buffer));
629
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));
639
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;
645                                 }
646                                 value = talloc_string_sub(ctx,
647                                                 value,
648                                                 "&",
649                                                 user_name);
650                         }
651                 }
652         }
653         nis_freeresult(result);
654
655         if (value) {
656                 value = strip_mount_options(ctx, value);
657                 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
658                                         user_name, value));
659         }
660         return value;
661 }
662 #else /* WITH_NISPLUS_HOME */
663
664 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
665 {
666         char *value = NULL;
667
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());
673
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;
677         }
678
679         DEBUG(5, ("NIS Domain: %s\n", nis_domain));
680
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';
686                 }
687                 value = talloc_strdup(ctx, nis_result);
688                 if (!value) {
689                         return NULL;
690                 }
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));
699         }
700
701         if (value) {
702                 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
703         }
704         return value;
705 }
706 #endif /* WITH_NISPLUS_HOME */
707 #endif
708
709 /****************************************************************************
710  Check if a process exists. Does this work on all unixes?
711 ****************************************************************************/
712
713 bool process_exists(const struct server_id pid)
714 {
715         if (procid_is_me(&pid)) {
716                 return True;
717         }
718
719         if (procid_is_local(&pid)) {
720                 return (kill(pid.pid,0) == 0 || errno != ESRCH);
721         }
722
723 #ifdef CLUSTER_SUPPORT
724         return ctdbd_process_exists(messaging_ctdbd_connection(),
725                                     pid.vnn, pid.pid);
726 #else
727         return False;
728 #endif
729 }
730
731 bool processes_exist(const struct server_id *pids, int num_pids,
732                      bool *results)
733 {
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;
739
740         remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
741         if (remote_pids == NULL) {
742                 goto fail;
743         }
744         remote_idx = talloc_array(talloc_tos(), int, num_pids);
745         if (remote_idx == NULL) {
746                 goto fail;
747         }
748         remote_results = talloc_array(talloc_tos(), bool, num_pids);
749         if (remote_results == NULL) {
750                 goto fail;
751         }
752
753         num_remote_pids = 0;
754
755         for (i=0; i<num_pids; i++) {
756                 if (procid_is_me(&pids[i])) {
757                         results[i] = true;
758                         continue;
759                 }
760                 if (procid_is_local(&pids[i])) {
761                         results[i] = ((kill(pids[i].pid,0) == 0) ||
762                                       (errno != ESRCH));
763                         continue;
764                 }
765
766                 remote_pids[num_remote_pids] = pids[i];
767                 remote_idx[num_remote_pids] = i;
768                 num_remote_pids += 1;
769         }
770
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;
777                 }
778 #else
779                 for (i=0; i<num_remote_pids; i++) {
780                         remote_results[i] = false;
781                 }
782 #endif
783
784                 for (i=0; i<num_remote_pids; i++) {
785                         results[remote_idx[i]] = remote_results[i];
786                 }
787         }
788
789         result = true;
790 fail:
791         TALLOC_FREE(remote_results);
792         TALLOC_FREE(remote_idx);
793         TALLOC_FREE(remote_pids);
794         return result;
795 }
796
797 /*******************************************************************
798  Convert a uid into a user name.
799 ********************************************************************/
800
801 const char *uidtoname(uid_t uid)
802 {
803         TALLOC_CTX *ctx = talloc_tos();
804         char *name = NULL;
805         struct passwd *pass = NULL;
806
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);
815         }
816         return name;
817 }
818
819 /*******************************************************************
820  Convert a gid into a group name.
821 ********************************************************************/
822
823 char *gidtoname(gid_t gid)
824 {
825         struct group *grp;
826
827         grp = getgrgid(gid);
828         if (grp) {
829                 return talloc_strdup(talloc_tos(), grp->gr_name);
830         }
831         else {
832                 return talloc_asprintf(talloc_tos(),
833                                         "%d",
834                                         (int)gid);
835         }
836 }
837
838 /*******************************************************************
839  Convert a user name into a uid.
840 ********************************************************************/
841
842 uid_t nametouid(const char *name)
843 {
844         struct passwd *pass;
845         char *p;
846         uid_t u;
847
848         pass = Get_Pwnam_alloc(talloc_tos(), name);
849         if (pass) {
850                 u = pass->pw_uid;
851                 TALLOC_FREE(pass);
852                 return u;
853         }
854
855         u = (uid_t)strtol(name, &p, 0);
856         if ((p != name) && (*p == '\0'))
857                 return u;
858
859         return (uid_t)-1;
860 }
861
862 /*******************************************************************
863  Convert a name to a gid_t if possible. Return -1 if not a group. 
864 ********************************************************************/
865
866 gid_t nametogid(const char *name)
867 {
868         struct group *grp;
869         char *p;
870         gid_t g;
871
872         g = (gid_t)strtol(name, &p, 0);
873         if ((p != name) && (*p == '\0'))
874                 return g;
875
876         grp = getgrnam(name);
877         if (grp)
878                 return(grp->gr_gid);
879         return (gid_t)-1;
880 }
881
882 /*******************************************************************
883  Something really nasty happened - panic !
884 ********************************************************************/
885
886 void smb_panic_s3(const char *why)
887 {
888         char *cmd;
889         int result;
890
891         DEBUG(0,("PANIC (pid %llu): %s\n",
892                     (unsigned long long)getpid(), why));
893         log_stack_trace();
894
895 #if defined(HAVE_PRCTL) && defined(PR_SET_PTRACER)
896         /*
897          * Make sure all children can attach a debugger.
898          */
899         prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
900 #endif
901
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);
906
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)));
913         }
914
915         dump_core();
916 }
917
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 ********************************************************************/
923
924 #ifdef HAVE_LIBUNWIND_H
925 #include <libunwind.h>
926 #endif
927
928 #ifdef HAVE_EXECINFO_H
929 #include <execinfo.h>
930 #endif
931
932 #ifdef HAVE_LIBEXC_H
933 #include <libexc.h>
934 #endif
935
936 void log_stack_trace(void)
937 {
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.
942          */ 
943         unw_cursor_t cursor;
944         unw_context_t uc;
945         unsigned i = 0;
946
947         char procname[256];
948         unw_word_t ip, sp, off;
949
950         procname[sizeof(procname) - 1] = '\0';
951
952         if (unw_getcontext(&uc) != 0) {
953                 goto libunwind_failed;
954         }
955
956         if (unw_init_local(&cursor, &uc) != 0) {
957                 goto libunwind_failed;
958         }
959
960         DEBUG(0, ("BACKTRACE:\n"));
961
962         do {
963             ip = sp = 0;
964             unw_get_reg(&cursor, UNW_REG_IP, &ip);
965             unw_get_reg(&cursor, UNW_REG_SP, &sp);
966
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));
984             }
985             ++i;
986         } while (unw_step(&cursor) > 0);
987
988         return;
989
990 libunwind_failed:
991         DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
992
993 #elif HAVE_BACKTRACE_SYMBOLS
994         void *backtrace_stack[BACKTRACE_STACK_SIZE];
995         size_t backtrace_size;
996         char **backtrace_strings;
997
998         /* get the backtrace (stack frames) */
999         backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1000         backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1001
1002         DEBUG(0, ("BACKTRACE: %lu stack frames:\n", 
1003                   (unsigned long)backtrace_size));
1004
1005         if (backtrace_strings) {
1006                 int i;
1007
1008                 for (i = 0; i < backtrace_size; i++)
1009                         DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1010
1011                 /* Leak the backtrace_strings, rather than risk what free() might do */
1012         }
1013
1014 #elif HAVE_LIBEXC
1015
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.
1019          */
1020
1021 #define NAMESIZE 32 /* Arbitrary */
1022
1023         __uint64_t      addrs[BACKTRACE_STACK_SIZE];
1024         char *          names[BACKTRACE_STACK_SIZE];
1025         char            namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1026
1027         int             i;
1028         int             levels;
1029
1030         ZERO_ARRAY(addrs);
1031         ZERO_ARRAY(names);
1032         ZERO_ARRAY(namebuf);
1033
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.
1036          */
1037         become_root();
1038
1039         for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1040                 names[i] = namebuf + (i * NAMESIZE);
1041         }
1042
1043         levels = trace_back_stack(0, addrs, names,
1044                         BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1045
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]));
1049         }
1050 #undef NAMESIZE
1051
1052 #else
1053         DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1054 #endif
1055 }
1056
1057 /*******************************************************************
1058   A readdir wrapper which just returns the file name.
1059  ********************************************************************/
1060
1061 const char *readdirname(DIR *p)
1062 {
1063         struct dirent *ptr;
1064         char *dname;
1065
1066         if (!p)
1067                 return(NULL);
1068
1069         ptr = (struct dirent *)readdir(p);
1070         if (!ptr)
1071                 return(NULL);
1072
1073         dname = ptr->d_name;
1074
1075 #ifdef NEXT2
1076         if (telldir(p) < 0)
1077                 return(NULL);
1078 #endif
1079
1080 #ifdef HAVE_BROKEN_READDIR_NAME
1081         /* using /usr/ucb/cc is BAD */
1082         dname = dname - 2;
1083 #endif
1084
1085         return talloc_strdup(talloc_tos(), dname);
1086 }
1087
1088 /*******************************************************************
1089  Utility function used to decide if the last component 
1090  of a path matches a (possibly wildcarded) entry in a namelist.
1091 ********************************************************************/
1092
1093 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1094 {
1095         const char *last_component;
1096
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;
1100         }
1101
1102         DEBUG(8, ("is_in_path: %s\n", name));
1103
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 '/' */
1110         }
1111
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;
1117                         }
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;
1123                         }
1124                 }
1125         }
1126         DEBUG(8,("is_in_path: match not found\n"));
1127         return False;
1128 }
1129
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 ********************************************************************/
1140
1141 void set_namearray(name_compare_entry **ppname_array, const char *namelist_in)
1142 {
1143         char *name_end;
1144         char *namelist;
1145         char *nameptr;
1146         int num_entries = 0;
1147         int i;
1148
1149         (*ppname_array) = NULL;
1150
1151         if((namelist_in == NULL ) || ((namelist_in != NULL) && (*namelist_in == '\0'))) 
1152                 return;
1153
1154         namelist = talloc_strdup(talloc_tos(), namelist_in);
1155         if (namelist == NULL) {
1156                 DEBUG(0,("set_namearray: talloc fail\n"));
1157                 return;
1158         }
1159         nameptr = namelist;
1160
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.
1164         */
1165
1166         while(*nameptr) {
1167                 if ( *nameptr == '/' ) {
1168                         /* cope with multiple (useless) /s) */
1169                         nameptr++;
1170                         continue;
1171                 }
1172                 /* anything left? */
1173                 if ( *nameptr == '\0' )
1174                         break;
1175
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);
1180
1181                 /* next segment please */
1182                 nameptr = name_end + 1;
1183                 num_entries++;
1184         }
1185
1186         if(num_entries == 0) {
1187                 talloc_free(namelist);
1188                 return;
1189         }
1190
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;
1195         }
1196
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;
1205                 }
1206                 /* anything left? */
1207                 if ( *nameptr == '\0' )
1208                         break;
1209
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);
1216
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;
1222                 }
1223
1224                 /* next segment please */
1225                 nameptr = name_end + 1;
1226                 i++;
1227         }
1228
1229         (*ppname_array)[i].name = NULL;
1230
1231         talloc_free(namelist);
1232         return;
1233 }
1234
1235 #undef DBGC_CLASS
1236 #define DBGC_CLASS DBGC_LOCKING
1237
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 ****************************************************************************/
1244
1245 bool fcntl_getlock(int fd, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
1246 {
1247         struct flock lock;
1248         int ret;
1249
1250         DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1251                     fd,(double)*poffset,(double)*pcount,*ptype));
1252
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;
1258
1259         ret = sys_fcntl_ptr(fd,F_GETLK,&lock);
1260
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;
1267         }
1268
1269         *ptype = lock.l_type;
1270         *poffset = lock.l_start;
1271         *pcount = lock.l_len;
1272         *ppid = lock.l_pid;
1273
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;
1277 }
1278
1279 #undef DBGC_CLASS
1280 #define DBGC_CLASS DBGC_ALL
1281
1282 /*******************************************************************
1283  Is the name specified one of my netbios names.
1284  Returns true if it is equal, false otherwise.
1285 ********************************************************************/
1286
1287 bool is_myname(const char *s)
1288 {
1289         int n;
1290         bool ret = False;
1291
1292         for (n=0; my_netbios_names(n); n++) {
1293                 if (strequal(my_netbios_names(n), s)) {
1294                         ret=True;
1295                         break;
1296                 }
1297         }
1298         DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1299         return(ret);
1300 }
1301
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 ********************************************************************/
1312
1313 void ra_lanman_string( const char *native_lanman )
1314 {
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 );
1321 }
1322
1323 static const char *remote_arch_str;
1324
1325 const char *get_remote_arch_str(void)
1326 {
1327         if (!remote_arch_str) {
1328                 return "UNKNOWN";
1329         }
1330         return remote_arch_str;
1331 }
1332
1333 /*******************************************************************
1334  Set the horrid remote_arch string based on an enum.
1335 ********************************************************************/
1336
1337 void set_remote_arch(enum remote_arch_types type)
1338 {
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;
1381         }
1382
1383         DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1384                                 remote_arch_str));
1385 }
1386
1387 /*******************************************************************
1388  Get the remote_arch type.
1389 ********************************************************************/
1390
1391 enum remote_arch_types get_remote_arch(void)
1392 {
1393         return ra_type;
1394 }
1395
1396 const char *tab_depth(int level, int depth)
1397 {
1398         if( CHECK_DEBUGLVL(level) ) {
1399                 dbgtext("%*s", depth*4, "");
1400         }
1401         return "";
1402 }
1403
1404 /*****************************************************************************
1405  Provide a checksum on a string
1406
1407  Input:  s - the null-terminated character string for which the checksum
1408              will be calculated.
1409
1410   Output: The checksum value calculated for s.
1411 *****************************************************************************/
1412
1413 int str_checksum(const char *s)
1414 {
1415         if (s == NULL)
1416                 return 0;
1417         return hash(s, strlen(s), 0);
1418 }
1419
1420 /*****************************************************************
1421  Zero a memory area then free it. Used to catch bugs faster.
1422 *****************************************************************/  
1423
1424 void zero_free(void *p, size_t size)
1425 {
1426         memset(p, 0, size);
1427         SAFE_FREE(p);
1428 }
1429
1430 /*****************************************************************
1431  Set our open file limit to a requested max and return the limit.
1432 *****************************************************************/  
1433
1434 int set_maxfiles(int requested_max)
1435 {
1436 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1437         struct rlimit rlp;
1438         int saved_current_limit;
1439
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;
1445         }
1446
1447         /* 
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.
1454          */
1455
1456         /* Try raising the hard (max) limit to the requested amount. */
1457
1458 #if defined(RLIM_INFINITY)
1459         if (rlp.rlim_max != RLIM_INFINITY) {
1460                 int orig_max = rlp.rlim_max;
1461
1462                 if ( rlp.rlim_max < requested_max )
1463                         rlp.rlim_max = requested_max;
1464
1465                 /* This failing is not an error - many systems (Linux) don't
1466                         support our default request of 10,000 open files. JRA. */
1467
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) ));
1471
1472                         /* Set failed - restore original value from get. */
1473                         rlp.rlim_max = orig_max;
1474                 }
1475         }
1476 #endif
1477
1478         /* Now try setting the soft (current) limit. */
1479
1480         saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1481
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;
1487         }
1488
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;
1494     }
1495
1496 #if defined(RLIM_INFINITY)
1497         if(rlp.rlim_cur == RLIM_INFINITY)
1498                 return saved_current_limit;
1499 #endif
1500
1501         if((int)rlp.rlim_cur > saved_current_limit)
1502                 return saved_current_limit;
1503
1504         return rlp.rlim_cur;
1505 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1506         /*
1507          * No way to know - just guess...
1508          */
1509         return requested_max;
1510 #endif
1511 }
1512
1513 /*****************************************************************
1514  malloc that aborts with smb_panic on fail or zero size.
1515  *****************************************************************/  
1516
1517 void *smb_xmalloc_array(size_t size, unsigned int count)
1518 {
1519         void *p;
1520         if (size == 0) {
1521                 smb_panic("smb_xmalloc_array: called with zero size");
1522         }
1523         if (count >= MAX_ALLOC_SIZE/size) {
1524                 smb_panic("smb_xmalloc_array: alloc size too large");
1525         }
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");
1530         }
1531         return p;
1532 }
1533
1534 /*
1535   vasprintf that aborts on malloc fail
1536 */
1537
1538  int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1539 {
1540         int n;
1541         va_list ap2;
1542
1543         va_copy(ap2, ap);
1544
1545         n = vasprintf(ptr, format, ap2);
1546         va_end(ap2);
1547         if (n == -1 || ! *ptr) {
1548                 smb_panic("smb_xvasprintf: out of memory");
1549         }
1550         return n;
1551 }
1552
1553 /*****************************************************************
1554  Get local hostname and cache result.
1555 *****************************************************************/
1556
1557 char *myhostname(void)
1558 {
1559         static char *ret;
1560         if (ret == NULL) {
1561                 ret = get_myname(NULL);
1562         }
1563         return ret;
1564 }
1565
1566 /*****************************************************************
1567  Get local hostname and cache result.
1568 *****************************************************************/
1569
1570 char *myhostname_upper(void)
1571 {
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);
1578         }
1579         return ret;
1580 }
1581
1582 /**
1583  * @brief Returns an absolute path to a file concatenating the provided
1584  * @a rootpath and @a basename
1585  *
1586  * @param name Filename, relative to @a rootpath
1587  *
1588  * @retval Pointer to a string containing the full path.
1589  **/
1590
1591 static char *xx_path(const char *name, const char *rootpath)
1592 {
1593         char *fname = NULL;
1594
1595         fname = talloc_strdup(talloc_tos(), rootpath);
1596         if (!fname) {
1597                 return NULL;
1598         }
1599         trim_string(fname,"","/");
1600
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)));
1605         }
1606
1607         return talloc_asprintf(talloc_tos(),
1608                                 "%s/%s",
1609                                 fname,
1610                                 name);
1611 }
1612
1613 /**
1614  * @brief Returns an absolute path to a file in the Samba lock directory.
1615  *
1616  * @param name File to find, relative to LOCKDIR.
1617  *
1618  * @retval Pointer to a talloc'ed string containing the full path.
1619  **/
1620
1621 char *lock_path(const char *name)
1622 {
1623         return xx_path(name, lp_lockdir());
1624 }
1625
1626 /**
1627  * @brief Returns an absolute path to a file in the Samba state directory.
1628  *
1629  * @param name File to find, relative to STATEDIR.
1630  *
1631  * @retval Pointer to a talloc'ed string containing the full path.
1632  **/
1633
1634 char *state_path(const char *name)
1635 {
1636         return xx_path(name, lp_statedir());
1637 }
1638
1639 /**
1640  * @brief Returns an absolute path to a file in the Samba cache directory.
1641  *
1642  * @param name File to find, relative to CACHEDIR.
1643  *
1644  * @retval Pointer to a talloc'ed string containing the full path.
1645  **/
1646
1647 char *cache_path(const char *name)
1648 {
1649         return xx_path(name, lp_cachedir());
1650 }
1651
1652 /*******************************************************************
1653  Given a filename - get its directory name
1654 ********************************************************************/
1655
1656 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1657                     const char **name)
1658 {
1659         char *p;
1660         ptrdiff_t len;
1661
1662         p = strrchr_m(dir, '/'); /* Find final '/', if any */
1663
1664         if (p == NULL) {
1665                 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1666                         return False;
1667                 }
1668                 if (name) {
1669                         *name = dir;
1670                 }
1671                 return True;
1672         }
1673
1674         len = p-dir;
1675
1676         if (!(*parent = (char *)talloc_memdup(mem_ctx, dir, len+1))) {
1677                 return False;
1678         }
1679         (*parent)[len] = '\0';
1680
1681         if (name) {
1682                 *name = p+1;
1683         }
1684         return True;
1685 }
1686
1687 /*******************************************************************
1688  Determine if a pattern contains any Microsoft wildcard characters.
1689 *******************************************************************/
1690
1691 bool ms_has_wild(const char *s)
1692 {
1693         char c;
1694
1695         if (lp_posix_pathnames()) {
1696                 /* With posix pathnames no characters are wild. */
1697                 return False;
1698         }
1699
1700         while ((c = *s++)) {
1701                 switch (c) {
1702                 case '*':
1703                 case '?':
1704                 case '<':
1705                 case '>':
1706                 case '"':
1707                         return True;
1708                 }
1709         }
1710         return False;
1711 }
1712
1713 bool ms_has_wild_w(const smb_ucs2_t *s)
1714 {
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;
1725                 }
1726         }
1727         return False;
1728 }
1729
1730 /*******************************************************************
1731  A wrapper that handles case sensitivity and the special handling
1732  of the ".." name.
1733 *******************************************************************/
1734
1735 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
1736 {
1737         if (ISDOTDOT(string))
1738                 string = ".";
1739         if (ISDOT(pattern))
1740                 return False;
1741
1742         return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
1743 }
1744
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 *******************************************************************/
1750
1751 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
1752 {
1753         if (ISDOTDOT(string))
1754                 string = ".";
1755         if (ISDOT(pattern))
1756                 return False;
1757
1758         return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
1759 }
1760
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 *******************************************************************/
1765
1766 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
1767 {
1768        while (listLen-- > 0) {
1769                if (mask_match(string, *list++, is_case_sensitive))
1770                        return True;
1771        }
1772        return False;
1773 }
1774
1775 /*********************************************************
1776  Recursive routine that is called by unix_wild_match.
1777 *********************************************************/
1778
1779 static bool unix_do_match(const char *regexp, const char *str)
1780 {
1781         const char *p;
1782
1783         for( p = regexp; *p && *str; ) {
1784
1785                 switch(*p) {
1786                         case '?':
1787                                 str++;
1788                                 p++;
1789                                 break;
1790
1791                         case '*':
1792
1793                                 /*
1794                                  * Look for a character matching 
1795                                  * the one after the '*'.
1796                                  */
1797                                 p++;
1798                                 if(!*p)
1799                                         return true; /* Automatic match */
1800                                 while(*str) {
1801
1802                                         while(*str && (*p != *str))
1803                                                 str++;
1804
1805                                         /*
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.
1809                                          */
1810
1811                                         {
1812                                                 int matchcount=0;
1813
1814                                                 /*
1815                                                  * Eat all the characters that match, but count how many there were.
1816                                                  */
1817
1818                                                 while(*str && (*p == *str)) {
1819                                                         str++;
1820                                                         matchcount++;
1821                                                 }
1822
1823                                                 /*
1824                                                  * Now check that if the regexp had n identical characters that
1825                                                  * matchcount had at least that many matches.
1826                                                  */
1827
1828                                                 while ( *(p+1) && (*(p+1) == *p)) {
1829                                                         p++;
1830                                                         matchcount--;
1831                                                 }
1832
1833                                                 if ( matchcount <= 0 )
1834                                                         return false;
1835                                         }
1836
1837                                         str--; /* We've eaten the match char after the '*' */
1838
1839                                         if(unix_do_match(p, str))
1840                                                 return true;
1841
1842                                         if(!*str)
1843                                                 return false;
1844                                         else
1845                                                 str++;
1846                                 }
1847                                 return false;
1848
1849                         default:
1850                                 if(*str != *p)
1851                                         return false;
1852                                 str++;
1853                                 p++;
1854                                 break;
1855                 }
1856         }
1857
1858         if(!*p && !*str)
1859                 return true;
1860
1861         if (!*p && str[0] == '.' && str[1] == 0)
1862                 return true;
1863
1864         if (!*str && *p == '?') {
1865                 while (*p == '?')
1866                         p++;
1867                 return(!*p);
1868         }
1869
1870         if(!*str && (*p == '*' && p[1] == '\0'))
1871                 return true;
1872
1873         return false;
1874 }
1875
1876 /*******************************************************************
1877  Simple case insensitive interface to a UNIX wildcard matcher.
1878  Returns True if match, False if not.
1879 *******************************************************************/
1880
1881 bool unix_wild_match(const char *pattern, const char *string)
1882 {
1883         TALLOC_CTX *ctx = talloc_stackframe();
1884         char *p2;
1885         char *s2;
1886         char *p;
1887         bool ret = false;
1888
1889         p2 = talloc_strdup(ctx,pattern);
1890         s2 = talloc_strdup(ctx,string);
1891         if (!p2 || !s2) {
1892                 TALLOC_FREE(ctx);
1893                 return false;
1894         }
1895         if (!strlower_m(p2)) {
1896                 TALLOC_FREE(ctx);
1897                 return false;
1898         }
1899         if (!strlower_m(s2)) {
1900                 TALLOC_FREE(ctx);
1901                 return false;
1902         }
1903
1904         /* Remove any *? and ** from the pattern as they are meaningless */
1905         for(p = p2; *p; p++) {
1906                 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
1907                         memmove(&p[1], &p[2], strlen(&p[2])+1);
1908                 }
1909         }
1910
1911         if (strequal(p2,"*")) {
1912                 TALLOC_FREE(ctx);
1913                 return true;
1914         }
1915
1916         ret = unix_do_match(p2, s2);
1917         TALLOC_FREE(ctx);
1918         return ret;
1919 }
1920
1921 /**********************************************************************
1922  Converts a name to a fully qualified domain name.
1923  Returns true if lookup succeeded, false if not (then fqdn is set to name)
1924  Note we deliberately use gethostbyname here, not getaddrinfo as we want
1925  to examine the h_aliases and I don't know how to do that with getaddrinfo.
1926 ***********************************************************************/
1927
1928 bool name_to_fqdn(fstring fqdn, const char *name)
1929 {
1930         char *full = NULL;
1931         struct hostent *hp = gethostbyname(name);
1932
1933         if (!hp || !hp->h_name || !*hp->h_name) {
1934                 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
1935                 fstrcpy(fqdn, name);
1936                 return false;
1937         }
1938
1939         /* Find out if the fqdn is returned as an alias
1940          * to cope with /etc/hosts files where the first
1941          * name is not the fqdn but the short name */
1942         if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
1943                 int i;
1944                 for (i = 0; hp->h_aliases[i]; i++) {
1945                         if (strchr_m(hp->h_aliases[i], '.')) {
1946                                 full = hp->h_aliases[i];
1947                                 break;
1948                         }
1949                 }
1950         }
1951         if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
1952                 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
1953                 DEBUGADD(1, ("    Specifing the machine hostname for address 127.0.0.1 may lead\n"));
1954                 DEBUGADD(1, ("    to Kerberos authentication problems as localhost.localdomain\n"));
1955                 DEBUGADD(1, ("    may end up being used instead of the real machine FQDN.\n"));
1956                 full = hp->h_name;
1957         }
1958         if (!full) {
1959                 full = hp->h_name;
1960         }
1961
1962         DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
1963         fstrcpy(fqdn, full);
1964         return true;
1965 }
1966
1967 /**********************************************************************
1968  Append a DATA_BLOB to a talloc'ed object
1969 ***********************************************************************/
1970
1971 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
1972 {
1973         size_t old_size = 0;
1974         char *result;
1975
1976         if (blob.length == 0) {
1977                 return buf;
1978         }
1979
1980         if (buf != NULL) {
1981                 old_size = talloc_get_size(buf);
1982         }
1983
1984         result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
1985         if (result == NULL) {
1986                 return NULL;
1987         }
1988
1989         memcpy(result + old_size, blob.data, blob.length);
1990         return result;
1991 }
1992
1993 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
1994 {
1995         switch (share_access & ~FILE_SHARE_DELETE) {
1996                 case FILE_SHARE_NONE:
1997                         return DENY_ALL;
1998                 case FILE_SHARE_READ:
1999                         return DENY_WRITE;
2000                 case FILE_SHARE_WRITE:
2001                         return DENY_READ;
2002                 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2003                         return DENY_NONE;
2004         }
2005         if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2006                 return DENY_DOS;
2007         } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2008                 return DENY_FCB;
2009         }
2010
2011         return (uint32)-1;
2012 }
2013
2014 pid_t procid_to_pid(const struct server_id *proc)
2015 {
2016         return proc->pid;
2017 }
2018
2019 static uint32 my_vnn = NONCLUSTER_VNN;
2020
2021 void set_my_vnn(uint32 vnn)
2022 {
2023         DEBUG(10, ("vnn pid %d = %u\n", (int)getpid(), (unsigned int)vnn));
2024         my_vnn = vnn;
2025 }
2026
2027 uint32 get_my_vnn(void)
2028 {
2029         return my_vnn;
2030 }
2031
2032 static uint64_t my_unique_id = 0;
2033
2034 void set_my_unique_id(uint64_t unique_id)
2035 {
2036         my_unique_id = unique_id;
2037 }
2038
2039 struct server_id pid_to_procid(pid_t pid)
2040 {
2041         struct server_id result;
2042         result.pid = pid;
2043         result.task_id = 0;
2044         result.unique_id = my_unique_id;
2045         result.vnn = my_vnn;
2046         return result;
2047 }
2048
2049 struct server_id procid_self(void)
2050 {
2051         return pid_to_procid(getpid());
2052 }
2053
2054 static struct idr_context *task_id_tree;
2055
2056 static int free_task_id(struct server_id *server_id)
2057 {
2058         idr_remove(task_id_tree, server_id->task_id);
2059         return 0;
2060 }
2061
2062 /* Return a server_id with a unique task_id element.  Free the
2063  * returned pointer to de-allocate the task_id via a talloc destructor
2064  * (ie, use talloc_free()) */
2065 struct server_id *new_server_id_task(TALLOC_CTX *mem_ctx)
2066 {
2067         struct server_id *server_id;
2068         int task_id;
2069         if (!task_id_tree) {
2070                 task_id_tree = idr_init(NULL);
2071                 if (!task_id_tree) {
2072                         return NULL;
2073                 }
2074         }
2075
2076         server_id = talloc(mem_ctx, struct server_id);
2077
2078         if (!server_id) {
2079                 return NULL;
2080         }
2081         *server_id = procid_self();
2082
2083         /* 0 is the default server_id, so we need to start with 1 */
2084         task_id = idr_get_new_above(task_id_tree, server_id, 1, INT32_MAX);
2085
2086         if (task_id == -1) {
2087                 talloc_free(server_id);
2088                 return NULL;
2089         }
2090
2091         talloc_set_destructor(server_id, free_task_id);
2092         server_id->task_id = task_id;
2093         return server_id;
2094 }
2095
2096 bool procid_is_me(const struct server_id *pid)
2097 {
2098         if (pid->pid != getpid())
2099                 return False;
2100         if (pid->task_id != 0)
2101                 return False;
2102         if (pid->vnn != my_vnn)
2103                 return False;
2104         return True;
2105 }
2106
2107 struct server_id interpret_pid(const char *pid_string)
2108 {
2109         struct server_id result;
2110         unsigned long long pid;
2111         unsigned int vnn, task_id = 0;
2112
2113         ZERO_STRUCT(result);
2114
2115         /* We accept various forms with 1, 2 or 3 component forms
2116          * because the server_id_str() can print different forms, and
2117          * we want backwards compatibility for scripts that may call
2118          * smbclient. */
2119         if (sscanf(pid_string, "%u:%llu.%u", &vnn, &pid, &task_id) == 3) {
2120                 result.vnn = vnn;
2121                 result.pid = pid;
2122                 result.task_id = task_id;
2123         } else if (sscanf(pid_string, "%u:%llu", &vnn, &pid) == 2) {
2124                 result.vnn = vnn;
2125                 result.pid = pid;
2126                 result.task_id = 0;
2127         } else if (sscanf(pid_string, "%llu.%u", &pid, &task_id) == 2) {
2128                 result.vnn = get_my_vnn();
2129                 result.pid = pid;
2130                 result.task_id = task_id;
2131         } else if (sscanf(pid_string, "%llu", &pid) == 1) {
2132                 result.vnn = get_my_vnn();
2133                 result.pid = pid;
2134         } else {
2135                 result.vnn = NONCLUSTER_VNN;
2136                 result.pid = (uint64_t)-1;
2137         }
2138         return result;
2139 }
2140
2141 char *procid_str_static(const struct server_id *pid)
2142 {
2143         return server_id_str(talloc_tos(), pid);
2144 }
2145
2146 bool procid_valid(const struct server_id *pid)
2147 {
2148         return (pid->pid != (uint64_t)-1);
2149 }
2150
2151 bool procid_is_local(const struct server_id *pid)
2152 {
2153         return pid->vnn == my_vnn;
2154 }
2155
2156 /****************************************************************
2157  Check if an offset into a buffer is safe.
2158  If this returns True it's safe to indirect into the byte at
2159  pointer ptr+off.
2160 ****************************************************************/
2161
2162 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2163 {
2164         const char *end_base = buf_base + buf_len;
2165         char *end_ptr = ptr + off;
2166
2167         if (!buf_base || !ptr) {
2168                 return False;
2169         }
2170
2171         if (end_base < buf_base || end_ptr < ptr) {
2172                 return False; /* wrap. */
2173         }
2174
2175         if (end_ptr < end_base) {
2176                 return True;
2177         }
2178         return False;
2179 }
2180
2181 /****************************************************************
2182  Return a safe pointer into a buffer, or NULL.
2183 ****************************************************************/
2184
2185 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2186 {
2187         return is_offset_safe(buf_base, buf_len, ptr, off) ?
2188                         ptr + off : NULL;
2189 }
2190
2191 /****************************************************************
2192  Return a safe pointer into a string within a buffer, or NULL.
2193 ****************************************************************/
2194
2195 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2196 {
2197         if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2198                 return NULL;
2199         }
2200         /* Check if a valid string exists at this offset. */
2201         if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2202                 return NULL;
2203         }
2204         return ptr + off;
2205 }
2206
2207 /****************************************************************
2208  Return an SVAL at a pointer, or failval if beyond the end.
2209 ****************************************************************/
2210
2211 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2212 {
2213         /*
2214          * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2215          * NOT ptr[2].
2216          */
2217         if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2218                 return failval;
2219         }
2220         return SVAL(ptr,off);
2221 }
2222
2223 /****************************************************************
2224  Return an IVAL at a pointer, or failval if beyond the end.
2225 ****************************************************************/
2226
2227 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2228 {
2229         /*
2230          * Note we use off+3 here, not off+4 as IVAL accesses 
2231          * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2232          */
2233         if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2234                 return failval;
2235         }
2236         return IVAL(ptr,off);
2237 }
2238
2239 /****************************************************************
2240  Split DOM\user into DOM and user. Do not mix with winbind variants of that
2241  call (they take care of winbind separator and other winbind specific settings).
2242 ****************************************************************/
2243
2244 void split_domain_user(TALLOC_CTX *mem_ctx,
2245                        const char *full_name,
2246                        char **domain,
2247                        char **user)
2248 {
2249         const char *p = NULL;
2250
2251         p = strchr_m(full_name, '\\');
2252
2253         if (p != NULL) {
2254                 *domain = talloc_strndup(mem_ctx, full_name,
2255                                          PTR_DIFF(p, full_name));
2256                 *user = talloc_strdup(mem_ctx, p+1);
2257         } else {
2258                 *domain = talloc_strdup(mem_ctx, "");
2259                 *user = talloc_strdup(mem_ctx, full_name);
2260         }
2261 }
2262
2263 /****************************************************************
2264  strip off leading '\\' from a hostname
2265 ****************************************************************/
2266
2267 const char *strip_hostname(const char *s)
2268 {
2269         if (!s) {
2270                 return NULL;
2271         }
2272
2273         if (strlen_m(s) < 3) {
2274                 return s;
2275         }
2276
2277         if (s[0] == '\\') s++;
2278         if (s[0] == '\\') s++;
2279
2280         return s;
2281 }
2282
2283 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2284 {
2285         if (!NT_STATUS_IS_OK(err1)) {
2286                 *result = err1;
2287                 return true;
2288         }
2289         if (!NT_STATUS_IS_OK(err2)) {
2290                 *result = err2;
2291                 return true;
2292         }
2293         return false;
2294 }
2295
2296 int timeval_to_msec(struct timeval t)
2297 {
2298         return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;
2299 }
2300
2301 /*******************************************************************
2302  Check a given DOS pathname is valid for a share.
2303 ********************************************************************/
2304
2305 char *valid_share_pathname(TALLOC_CTX *ctx, const char *dos_pathname)
2306 {
2307         char *ptr = NULL;
2308
2309         if (!dos_pathname) {
2310                 return NULL;
2311         }
2312
2313         ptr = talloc_strdup(ctx, dos_pathname);
2314         if (!ptr) {
2315                 return NULL;
2316         }
2317         /* Convert any '\' paths to '/' */
2318         unix_format(ptr);
2319         ptr = unix_clean_name(ctx, ptr);
2320         if (!ptr) {
2321                 return NULL;
2322         }
2323
2324         /* NT is braindead - it wants a C: prefix to a pathname ! So strip it. */
2325         if (strlen(ptr) > 2 && ptr[1] == ':' && ptr[0] != '/')
2326                 ptr += 2;
2327
2328         /* Only absolute paths allowed. */
2329         if (*ptr != '/')
2330                 return NULL;
2331
2332         return ptr;
2333 }
2334
2335 /*******************************************************************
2336  Return True if the filename is one of the special executable types.
2337 ********************************************************************/
2338
2339 bool is_executable(const char *fname)
2340 {
2341         if ((fname = strrchr_m(fname,'.'))) {
2342                 if (strequal(fname,".com") ||
2343                     strequal(fname,".dll") ||
2344                     strequal(fname,".exe") ||
2345                     strequal(fname,".sym")) {
2346                         return True;
2347                 }
2348         }
2349         return False;
2350 }
2351
2352 /****************************************************************************
2353  Open a file with a share mode - old openX method - map into NTCreate.
2354 ****************************************************************************/
2355
2356 bool map_open_params_to_ntcreate(const char *smb_base_fname,
2357                                  int deny_mode, int open_func,
2358                                  uint32 *paccess_mask,
2359                                  uint32 *pshare_mode,
2360                                  uint32 *pcreate_disposition,
2361                                  uint32 *pcreate_options,
2362                                  uint32_t *pprivate_flags)
2363 {
2364         uint32 access_mask;
2365         uint32 share_mode;
2366         uint32 create_disposition;
2367         uint32 create_options = FILE_NON_DIRECTORY_FILE;
2368         uint32_t private_flags = 0;
2369
2370         DEBUG(10,("map_open_params_to_ntcreate: fname = %s, deny_mode = 0x%x, "
2371                   "open_func = 0x%x\n",
2372                   smb_base_fname, (unsigned int)deny_mode,
2373                   (unsigned int)open_func ));
2374
2375         /* Create the NT compatible access_mask. */
2376         switch (GET_OPENX_MODE(deny_mode)) {
2377                 case DOS_OPEN_EXEC: /* Implies read-only - used to be FILE_READ_DATA */
2378                 case DOS_OPEN_RDONLY:
2379                         access_mask = FILE_GENERIC_READ;
2380                         break;
2381                 case DOS_OPEN_WRONLY:
2382                         access_mask = FILE_GENERIC_WRITE;
2383                         break;
2384                 case DOS_OPEN_RDWR:
2385                 case DOS_OPEN_FCB:
2386                         access_mask = FILE_GENERIC_READ|FILE_GENERIC_WRITE;
2387                         break;
2388                 default:
2389                         DEBUG(10,("map_open_params_to_ntcreate: bad open mode = 0x%x\n",
2390                                   (unsigned int)GET_OPENX_MODE(deny_mode)));
2391                         return False;
2392         }
2393
2394         /* Create the NT compatible create_disposition. */
2395         switch (open_func) {
2396                 case OPENX_FILE_EXISTS_FAIL|OPENX_FILE_CREATE_IF_NOT_EXIST:
2397                         create_disposition = FILE_CREATE;
2398                         break;
2399
2400                 case OPENX_FILE_EXISTS_OPEN:
2401                         create_disposition = FILE_OPEN;
2402                         break;
2403
2404                 case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
2405                         create_disposition = FILE_OPEN_IF;
2406                         break;
2407
2408                 case OPENX_FILE_EXISTS_TRUNCATE:
2409                         create_disposition = FILE_OVERWRITE;
2410                         break;
2411
2412                 case OPENX_FILE_EXISTS_TRUNCATE|OPENX_FILE_CREATE_IF_NOT_EXIST:
2413                         create_disposition = FILE_OVERWRITE_IF;
2414                         break;
2415
2416                 default:
2417                         /* From samba4 - to be confirmed. */
2418                         if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_EXEC) {
2419                                 create_disposition = FILE_CREATE;
2420                                 break;
2421                         }
2422                         DEBUG(10,("map_open_params_to_ntcreate: bad "
2423                                   "open_func 0x%x\n", (unsigned int)open_func));
2424                         return False;
2425         }
2426
2427         /* Create the NT compatible share modes. */
2428         switch (GET_DENY_MODE(deny_mode)) {
2429                 case DENY_ALL:
2430                         share_mode = FILE_SHARE_NONE;
2431                         break;
2432
2433                 case DENY_WRITE:
2434                         share_mode = FILE_SHARE_READ;
2435                         break;
2436
2437                 case DENY_READ:
2438                         share_mode = FILE_SHARE_WRITE;
2439                         break;
2440
2441                 case DENY_NONE:
2442                         share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2443                         break;
2444
2445                 case DENY_DOS:
2446                         private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
2447                         if (is_executable(smb_base_fname)) {
2448                                 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
2449                         } else {
2450                                 if (GET_OPENX_MODE(deny_mode) == DOS_OPEN_RDONLY) {
2451                                         share_mode = FILE_SHARE_READ;
2452                                 } else {
2453                                         share_mode = FILE_SHARE_NONE;
2454                                 }
2455                         }
2456                         break;
2457
2458                 case DENY_FCB:
2459                         private_flags |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
2460                         share_mode = FILE_SHARE_NONE;
2461                         break;
2462
2463                 default:
2464                         DEBUG(10,("map_open_params_to_ntcreate: bad deny_mode 0x%x\n",
2465                                 (unsigned int)GET_DENY_MODE(deny_mode) ));
2466                         return False;
2467         }
2468
2469         DEBUG(10,("map_open_params_to_ntcreate: file %s, access_mask = 0x%x, "
2470                   "share_mode = 0x%x, create_disposition = 0x%x, "
2471                   "create_options = 0x%x private_flags = 0x%x\n",
2472                   smb_base_fname,
2473                   (unsigned int)access_mask,
2474                   (unsigned int)share_mode,
2475                   (unsigned int)create_disposition,
2476                   (unsigned int)create_options,
2477                   (unsigned int)private_flags));
2478
2479         if (paccess_mask) {
2480                 *paccess_mask = access_mask;
2481         }
2482         if (pshare_mode) {
2483                 *pshare_mode = share_mode;
2484         }
2485         if (pcreate_disposition) {
2486                 *pcreate_disposition = create_disposition;
2487         }
2488         if (pcreate_options) {
2489                 *pcreate_options = create_options;
2490         }
2491         if (pprivate_flags) {
2492                 *pprivate_flags = private_flags;
2493         }
2494
2495         return True;
2496
2497 }
2498
2499 /*************************************************************************
2500  Return a talloced copy of a struct security_unix_token. NULL on fail.
2501 *************************************************************************/
2502
2503 struct security_unix_token *copy_unix_token(TALLOC_CTX *ctx, const struct security_unix_token *tok)
2504 {
2505         struct security_unix_token *cpy;
2506
2507         cpy = talloc(ctx, struct security_unix_token);
2508         if (!cpy) {
2509                 return NULL;
2510         }
2511
2512         cpy->uid = tok->uid;
2513         cpy->gid = tok->gid;
2514         cpy->ngroups = tok->ngroups;
2515         if (tok->ngroups) {
2516                 /* Make this a talloc child of cpy. */
2517                 cpy->groups = (gid_t *)talloc_memdup(
2518                         cpy, tok->groups, tok->ngroups * sizeof(gid_t));
2519                 if (!cpy->groups) {
2520                         TALLOC_FREE(cpy);
2521                         return NULL;
2522                 }
2523         } else {
2524                 cpy->groups = NULL;
2525         }
2526         return cpy;
2527 }