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