s3: Use cli_writeall instead of cli_write
[Samba.git] / source3 / lib / util.c
blob71c18154df64c7f4822bf9f9fad9a7704f15d283
1 /*
2 Unix SMB/CIFS implementation.
3 Samba utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2007
6 Copyright (C) Simo Sorce 2001
7 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
8 Copyright (C) James Peach 2006
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "system/passwd.h"
26 #include "system/filesys.h"
27 #include "ctdbd_conn.h"
28 #include "../lib/util/util_pw.h"
29 #include "messages.h"
31 extern char *global_clobber_region_function;
32 extern unsigned int global_clobber_region_line;
34 /* Max allowable allococation - 256mb - 0x10000000 */
35 #define MAX_ALLOC_SIZE (1024*1024*256)
37 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
38 #ifdef WITH_NISPLUS_HOME
39 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
41 * The following lines are needed due to buggy include files
42 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
43 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
44 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
45 * an enum in /usr/include/rpcsvc/nis.h.
48 #if defined(GROUP)
49 #undef GROUP
50 #endif
52 #if defined(GROUP_OBJ)
53 #undef GROUP_OBJ
54 #endif
56 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
58 #include <rpcsvc/nis.h>
60 #endif /* WITH_NISPLUS_HOME */
61 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
63 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
65 enum protocol_types get_Protocol(void)
67 return Protocol;
70 void set_Protocol(enum protocol_types p)
72 Protocol = p;
75 static enum remote_arch_types ra_type = RA_UNKNOWN;
77 /***********************************************************************
78 Definitions for all names.
79 ***********************************************************************/
81 static char *smb_scope;
82 static int smb_num_netbios_names;
83 static char **smb_my_netbios_names;
85 /***********************************************************************
86 Allocate and set scope. Ensure upper case.
87 ***********************************************************************/
89 bool set_global_scope(const char *scope)
91 SAFE_FREE(smb_scope);
92 smb_scope = SMB_STRDUP(scope);
93 if (!smb_scope)
94 return False;
95 strupper_m(smb_scope);
96 return True;
99 /*********************************************************************
100 Ensure scope is never null string.
101 *********************************************************************/
103 const char *global_scope(void)
105 if (!smb_scope)
106 set_global_scope("");
107 return smb_scope;
110 static void free_netbios_names_array(void)
112 int i;
114 for (i = 0; i < smb_num_netbios_names; i++)
115 SAFE_FREE(smb_my_netbios_names[i]);
117 SAFE_FREE(smb_my_netbios_names);
118 smb_num_netbios_names = 0;
121 static bool allocate_my_netbios_names_array(size_t number)
123 free_netbios_names_array();
125 smb_num_netbios_names = number + 1;
126 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
128 if (!smb_my_netbios_names)
129 return False;
131 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
132 return True;
135 static bool set_my_netbios_names(const char *name, int i)
137 SAFE_FREE(smb_my_netbios_names[i]);
139 smb_my_netbios_names[i] = SMB_STRDUP(name);
140 if (!smb_my_netbios_names[i])
141 return False;
142 strupper_m(smb_my_netbios_names[i]);
143 return True;
146 /***********************************************************************
147 Free memory allocated to global objects
148 ***********************************************************************/
150 void gfree_names(void)
152 gfree_netbios_names();
153 SAFE_FREE( smb_scope );
154 free_netbios_names_array();
155 free_local_machine_name();
158 void gfree_all( void )
160 gfree_names();
161 gfree_loadparm();
162 gfree_case_tables();
163 gfree_charcnv();
164 gfree_interfaces();
165 gfree_debugsyms();
168 const char *my_netbios_names(int i)
170 return smb_my_netbios_names[i];
173 bool set_netbios_aliases(const char **str_array)
175 size_t namecount;
177 /* Work out the max number of netbios aliases that we have */
178 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
181 if ( global_myname() && *global_myname())
182 namecount++;
184 /* Allocate space for the netbios aliases */
185 if (!allocate_my_netbios_names_array(namecount))
186 return False;
188 /* Use the global_myname string first */
189 namecount=0;
190 if ( global_myname() && *global_myname()) {
191 set_my_netbios_names( global_myname(), namecount );
192 namecount++;
195 if (str_array) {
196 size_t i;
197 for ( i = 0; str_array[i] != NULL; i++) {
198 size_t n;
199 bool duplicate = False;
201 /* Look for duplicates */
202 for( n=0; n<namecount; n++ ) {
203 if( strequal( str_array[i], my_netbios_names(n) ) ) {
204 duplicate = True;
205 break;
208 if (!duplicate) {
209 if (!set_my_netbios_names(str_array[i], namecount))
210 return False;
211 namecount++;
215 return True;
218 /****************************************************************************
219 Common name initialization code.
220 ****************************************************************************/
222 bool init_names(void)
224 int n;
226 if (global_myname() == NULL || *global_myname() == '\0') {
227 if (!set_global_myname(myhostname())) {
228 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
229 return False;
233 if (!set_netbios_aliases(lp_netbios_aliases())) {
234 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
235 return False;
238 set_local_machine_name(global_myname(),false);
240 DEBUG( 5, ("Netbios name list:-\n") );
241 for( n=0; my_netbios_names(n); n++ ) {
242 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
243 n, my_netbios_names(n) ) );
246 return( True );
249 /*******************************************************************
250 Check if a file exists - call vfs_file_exist for samba files.
251 ********************************************************************/
253 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
254 bool fake_dir_create_times)
256 SMB_STRUCT_STAT st;
257 if (!sbuf)
258 sbuf = &st;
260 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
261 return(False);
263 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
266 /*******************************************************************
267 Check if a unix domain socket exists - call vfs_file_exist for samba files.
268 ********************************************************************/
270 bool socket_exist(const char *fname)
272 SMB_STRUCT_STAT st;
273 if (sys_stat(fname, &st, false) != 0)
274 return(False);
276 return S_ISSOCK(st.st_ex_mode);
279 /*******************************************************************
280 Returns the size in bytes of the named given the stat struct.
281 ********************************************************************/
283 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
285 return sbuf->st_ex_size;
288 /*******************************************************************
289 Returns the size in bytes of the named file.
290 ********************************************************************/
292 SMB_OFF_T get_file_size(char *file_name)
294 SMB_STRUCT_STAT buf;
295 buf.st_ex_size = 0;
296 if (sys_stat(file_name, &buf, false) != 0)
297 return (SMB_OFF_T)-1;
298 return get_file_size_stat(&buf);
301 /*******************************************************************
302 Return a string representing an attribute for a file.
303 ********************************************************************/
305 char *attrib_string(uint16 mode)
307 fstring attrstr;
309 attrstr[0] = 0;
311 if (mode & aVOLID) fstrcat(attrstr,"V");
312 if (mode & aDIR) fstrcat(attrstr,"D");
313 if (mode & aARCH) fstrcat(attrstr,"A");
314 if (mode & aHIDDEN) fstrcat(attrstr,"H");
315 if (mode & aSYSTEM) fstrcat(attrstr,"S");
316 if (mode & aRONLY) fstrcat(attrstr,"R");
318 return talloc_strdup(talloc_tos(), attrstr);
321 /*******************************************************************
322 Show a smb message structure.
323 ********************************************************************/
325 void show_msg(char *buf)
327 int i;
328 int bcc=0;
330 if (!DEBUGLVL(5))
331 return;
333 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
334 smb_len(buf),
335 (int)CVAL(buf,smb_com),
336 (int)CVAL(buf,smb_rcls),
337 (int)CVAL(buf,smb_reh),
338 (int)SVAL(buf,smb_err),
339 (int)CVAL(buf,smb_flg),
340 (int)SVAL(buf,smb_flg2)));
341 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
342 (int)SVAL(buf,smb_tid),
343 (int)SVAL(buf,smb_pid),
344 (int)SVAL(buf,smb_uid),
345 (int)SVAL(buf,smb_mid)));
346 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
348 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
349 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
350 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
352 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
354 DEBUGADD(5,("smb_bcc=%d\n",bcc));
356 if (DEBUGLEVEL < 10)
357 return;
359 if (DEBUGLEVEL < 50)
360 bcc = MIN(bcc, 512);
362 dump_data(10, (uint8 *)smb_buf(buf), bcc);
365 /*******************************************************************
366 Set the length and marker of an encrypted smb packet.
367 ********************************************************************/
369 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
371 _smb_setlen(buf,len);
373 SCVAL(buf,4,0xFF);
374 SCVAL(buf,5,'E');
375 SSVAL(buf,6,enc_ctx_num);
378 /*******************************************************************
379 Set the length and marker of an smb packet.
380 ********************************************************************/
382 void smb_setlen(char *buf,int len)
384 _smb_setlen(buf,len);
386 SCVAL(buf,4,0xFF);
387 SCVAL(buf,5,'S');
388 SCVAL(buf,6,'M');
389 SCVAL(buf,7,'B');
392 /*******************************************************************
393 Setup only the byte count for a smb message.
394 ********************************************************************/
396 int set_message_bcc(char *buf,int num_bytes)
398 int num_words = CVAL(buf,smb_wct);
399 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
400 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
401 return (smb_size + num_words*2 + num_bytes);
404 /*******************************************************************
405 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
406 Return the bytes added
407 ********************************************************************/
409 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
411 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
412 uint8 *tmp;
414 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
415 DEBUG(0, ("talloc failed\n"));
416 return -1;
418 *outbuf = tmp;
420 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
421 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
422 return blob.length;
425 /*******************************************************************
426 Reduce a file name, removing .. elements.
427 ********************************************************************/
429 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
431 char *p = NULL;
432 char *str = NULL;
434 DEBUG(3,("dos_clean_name [%s]\n",s));
436 /* remove any double slashes */
437 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
438 if (!str) {
439 return NULL;
442 /* Remove leading .\\ characters */
443 if(strncmp(str, ".\\", 2) == 0) {
444 trim_string(str, ".\\", NULL);
445 if(*str == 0) {
446 str = talloc_strdup(ctx, ".\\");
447 if (!str) {
448 return NULL;
453 while ((p = strstr_m(str,"\\..\\")) != NULL) {
454 char *s1;
456 *p = 0;
457 s1 = p+3;
459 if ((p=strrchr_m(str,'\\')) != NULL) {
460 *p = 0;
461 } else {
462 *str = 0;
464 str = talloc_asprintf(ctx,
465 "%s%s",
466 str,
467 s1);
468 if (!str) {
469 return NULL;
473 trim_string(str,NULL,"\\..");
474 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
477 /*******************************************************************
478 Reduce a file name, removing .. elements.
479 ********************************************************************/
481 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
483 char *p = NULL;
484 char *str = NULL;
486 DEBUG(3,("unix_clean_name [%s]\n",s));
488 /* remove any double slashes */
489 str = talloc_all_string_sub(ctx, s, "//","/");
490 if (!str) {
491 return NULL;
494 /* Remove leading ./ characters */
495 if(strncmp(str, "./", 2) == 0) {
496 trim_string(str, "./", NULL);
497 if(*str == 0) {
498 str = talloc_strdup(ctx, "./");
499 if (!str) {
500 return NULL;
505 while ((p = strstr_m(str,"/../")) != NULL) {
506 char *s1;
508 *p = 0;
509 s1 = p+3;
511 if ((p=strrchr_m(str,'/')) != NULL) {
512 *p = 0;
513 } else {
514 *str = 0;
516 str = talloc_asprintf(ctx,
517 "%s%s",
518 str,
519 s1);
520 if (!str) {
521 return NULL;
525 trim_string(str,NULL,"/..");
526 return talloc_all_string_sub(ctx, str, "/./", "/");
529 char *clean_name(TALLOC_CTX *ctx, const char *s)
531 char *str = dos_clean_name(ctx, s);
532 if (!str) {
533 return NULL;
535 return unix_clean_name(ctx, str);
538 /*******************************************************************
539 Write data into an fd at a given offset. Ignore seek errors.
540 ********************************************************************/
542 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
544 size_t total=0;
545 ssize_t ret;
547 if (pos == (SMB_OFF_T)-1) {
548 return write_data(fd, buffer, N);
550 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
551 while (total < N) {
552 ret = sys_pwrite(fd,buffer + total,N - total, pos);
553 if (ret == -1 && errno == ESPIPE) {
554 return write_data(fd, buffer + total,N - total);
556 if (ret == -1) {
557 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
558 return -1;
560 if (ret == 0) {
561 return total;
563 total += ret;
564 pos += ret;
566 return (ssize_t)total;
567 #else
568 /* Use lseek and write_data. */
569 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
570 if (errno != ESPIPE) {
571 return -1;
574 return write_data(fd, buffer, N);
575 #endif
579 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
580 struct event_context *ev_ctx,
581 struct server_id id,
582 bool parent_longlived)
584 NTSTATUS status = NT_STATUS_OK;
586 /* Reset the state of the random
587 * number generation system, so
588 * children do not get the same random
589 * numbers as each other */
590 set_need_random_reseed();
592 /* tdb needs special fork handling */
593 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
594 DEBUG(0,("tdb_reopen_all failed.\n"));
595 status = NT_STATUS_OPEN_FAILED;
596 goto done;
599 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
600 smb_panic(__location__ ": Failed to re-initialise event context");
603 if (msg_ctx) {
605 * For clustering, we need to re-init our ctdbd connection after the
606 * fork
608 status = messaging_reinit(msg_ctx, id);
609 if (!NT_STATUS_IS_OK(status)) {
610 DEBUG(0,("messaging_reinit() failed: %s\n",
611 nt_errstr(status)));
614 done:
615 return status;
618 #if defined(PARANOID_MALLOC_CHECKER)
620 /****************************************************************************
621 Internal malloc wrapper. Externally visible.
622 ****************************************************************************/
624 void *malloc_(size_t size)
626 if (size == 0) {
627 return NULL;
629 #undef malloc
630 return malloc(size);
631 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
634 /****************************************************************************
635 Internal calloc wrapper. Not externally visible.
636 ****************************************************************************/
638 static void *calloc_(size_t count, size_t size)
640 if (size == 0 || count == 0) {
641 return NULL;
643 #undef calloc
644 return calloc(count, size);
645 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
648 /****************************************************************************
649 Internal realloc wrapper. Not externally visible.
650 ****************************************************************************/
652 static void *realloc_(void *ptr, size_t size)
654 #undef realloc
655 return realloc(ptr, size);
656 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
659 #endif /* PARANOID_MALLOC_CHECKER */
661 /****************************************************************************
662 Type-safe memalign
663 ****************************************************************************/
665 void *memalign_array(size_t el_size, size_t align, unsigned int count)
667 if (count >= MAX_ALLOC_SIZE/el_size) {
668 return NULL;
671 return sys_memalign(align, el_size*count);
674 /****************************************************************************
675 Type-safe calloc.
676 ****************************************************************************/
678 void *calloc_array(size_t size, size_t nmemb)
680 if (nmemb >= MAX_ALLOC_SIZE/size) {
681 return NULL;
683 if (size == 0 || nmemb == 0) {
684 return NULL;
686 #if defined(PARANOID_MALLOC_CHECKER)
687 return calloc_(nmemb, size);
688 #else
689 return calloc(nmemb, size);
690 #endif
693 /****************************************************************************
694 Expand a pointer to be a particular size.
695 Note that this version of Realloc has an extra parameter that decides
696 whether to free the passed in storage on allocation failure or if the
697 new size is zero.
699 This is designed for use in the typical idiom of :
701 p = SMB_REALLOC(p, size)
702 if (!p) {
703 return error;
706 and not to have to keep track of the old 'p' contents to free later, nor
707 to worry if the size parameter was zero. In the case where NULL is returned
708 we guarentee that p has been freed.
710 If free later semantics are desired, then pass 'free_old_on_error' as False which
711 guarentees that the old contents are not freed on error, even if size == 0. To use
712 this idiom use :
714 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
715 if (!tmp) {
716 SAFE_FREE(p);
717 return error;
718 } else {
719 p = tmp;
722 Changes were instigated by Coverity error checking. JRA.
723 ****************************************************************************/
725 void *Realloc(void *p, size_t size, bool free_old_on_error)
727 void *ret=NULL;
729 if (size == 0) {
730 if (free_old_on_error) {
731 SAFE_FREE(p);
733 DEBUG(2,("Realloc asked for 0 bytes\n"));
734 return NULL;
737 #if defined(PARANOID_MALLOC_CHECKER)
738 if (!p) {
739 ret = (void *)malloc_(size);
740 } else {
741 ret = (void *)realloc_(p,size);
743 #else
744 if (!p) {
745 ret = (void *)malloc(size);
746 } else {
747 ret = (void *)realloc(p,size);
749 #endif
751 if (!ret) {
752 if (free_old_on_error && p) {
753 SAFE_FREE(p);
755 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
758 return(ret);
761 /****************************************************************************
762 (Hopefully) efficient array append.
763 ****************************************************************************/
765 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
766 void *element, void *_array, uint32 *num_elements,
767 ssize_t *array_size)
769 void **array = (void **)_array;
771 if (*array_size < 0) {
772 return;
775 if (*array == NULL) {
776 if (*array_size == 0) {
777 *array_size = 128;
780 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
781 goto error;
784 *array = TALLOC(mem_ctx, element_size * (*array_size));
785 if (*array == NULL) {
786 goto error;
790 if (*num_elements == *array_size) {
791 *array_size *= 2;
793 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
794 goto error;
797 *array = TALLOC_REALLOC(mem_ctx, *array,
798 element_size * (*array_size));
800 if (*array == NULL) {
801 goto error;
805 memcpy((char *)(*array) + element_size*(*num_elements),
806 element, element_size);
807 *num_elements += 1;
809 return;
811 error:
812 *num_elements = 0;
813 *array_size = -1;
816 /****************************************************************************
817 Get my own domain name, or "" if we have none.
818 ****************************************************************************/
820 char *get_mydnsdomname(TALLOC_CTX *ctx)
822 const char *domname;
823 char *p;
825 domname = get_mydnsfullname();
826 if (!domname) {
827 return NULL;
830 p = strchr_m(domname, '.');
831 if (p) {
832 p++;
833 return talloc_strdup(ctx, p);
834 } else {
835 return talloc_strdup(ctx, "");
839 /****************************************************************************
840 Interpret a protocol description string, with a default.
841 ****************************************************************************/
843 int interpret_protocol(const char *str,int def)
845 if (strequal(str,"NT1"))
846 return(PROTOCOL_NT1);
847 if (strequal(str,"LANMAN2"))
848 return(PROTOCOL_LANMAN2);
849 if (strequal(str,"LANMAN1"))
850 return(PROTOCOL_LANMAN1);
851 if (strequal(str,"CORE"))
852 return(PROTOCOL_CORE);
853 if (strequal(str,"COREPLUS"))
854 return(PROTOCOL_COREPLUS);
855 if (strequal(str,"CORE+"))
856 return(PROTOCOL_COREPLUS);
858 DEBUG(0,("Unrecognised protocol level %s\n",str));
860 return(def);
864 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
865 /******************************************************************
866 Remove any mount options such as -rsize=2048,wsize=2048 etc.
867 Based on a fix from <Thomas.Hepper@icem.de>.
868 Returns a malloc'ed string.
869 *******************************************************************/
871 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
873 if (*str == '-') {
874 const char *p = str;
875 while(*p && !isspace(*p))
876 p++;
877 while(*p && isspace(*p))
878 p++;
879 if(*p) {
880 return talloc_strdup(ctx, p);
883 return NULL;
886 /*******************************************************************
887 Patch from jkf@soton.ac.uk
888 Split Luke's automount_server into YP lookup and string splitter
889 so can easily implement automount_path().
890 Returns a malloc'ed string.
891 *******************************************************************/
893 #ifdef WITH_NISPLUS_HOME
894 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
896 char *value = NULL;
898 char *nis_map = (char *)lp_nis_home_map_name();
900 char buffer[NIS_MAXATTRVAL + 1];
901 nis_result *result;
902 nis_object *object;
903 entry_obj *entry;
905 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
906 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
908 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
909 if (result->status != NIS_SUCCESS) {
910 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
911 } else {
912 object = result->objects.objects_val;
913 if (object->zo_data.zo_type == ENTRY_OBJ) {
914 entry = &object->zo_data.objdata_u.en_data;
915 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
916 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
918 value = talloc_strdup(ctx,
919 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
920 if (!value) {
921 nis_freeresult(result);
922 return NULL;
924 value = talloc_string_sub(ctx,
925 value,
926 "&",
927 user_name);
931 nis_freeresult(result);
933 if (value) {
934 value = strip_mount_options(ctx, value);
935 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
936 user_name, value));
938 return value;
940 #else /* WITH_NISPLUS_HOME */
942 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
944 char *value = NULL;
946 int nis_error; /* returned by yp all functions */
947 char *nis_result; /* yp_match inits this */
948 int nis_result_len; /* and set this */
949 char *nis_domain; /* yp_get_default_domain inits this */
950 char *nis_map = (char *)lp_nis_home_map_name();
952 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
953 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
954 return NULL;
957 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
959 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
960 strlen(user_name), &nis_result,
961 &nis_result_len)) == 0) {
962 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
963 nis_result[nis_result_len] = '\0';
965 value = talloc_strdup(ctx, nis_result);
966 if (!value) {
967 return NULL;
969 value = strip_mount_options(ctx, value);
970 } else if(nis_error == YPERR_KEY) {
971 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
972 user_name, nis_map));
973 DEBUG(3, ("using defaults for server and home directory\n"));
974 } else {
975 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
976 yperr_string(nis_error), user_name, nis_map));
979 if (value) {
980 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
982 return value;
984 #endif /* WITH_NISPLUS_HOME */
985 #endif
987 /****************************************************************************
988 Check if a process exists. Does this work on all unixes?
989 ****************************************************************************/
991 bool process_exists(const struct server_id pid)
993 if (procid_is_me(&pid)) {
994 return True;
997 if (procid_is_local(&pid)) {
998 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1001 #ifdef CLUSTER_SUPPORT
1002 return ctdbd_process_exists(messaging_ctdbd_connection(),
1003 pid.vnn, pid.pid);
1004 #else
1005 return False;
1006 #endif
1009 /*******************************************************************
1010 Convert a uid into a user name.
1011 ********************************************************************/
1013 const char *uidtoname(uid_t uid)
1015 TALLOC_CTX *ctx = talloc_tos();
1016 char *name = NULL;
1017 struct passwd *pass = NULL;
1019 pass = getpwuid_alloc(ctx,uid);
1020 if (pass) {
1021 name = talloc_strdup(ctx,pass->pw_name);
1022 TALLOC_FREE(pass);
1023 } else {
1024 name = talloc_asprintf(ctx,
1025 "%ld",
1026 (long int)uid);
1028 return name;
1031 /*******************************************************************
1032 Convert a gid into a group name.
1033 ********************************************************************/
1035 char *gidtoname(gid_t gid)
1037 struct group *grp;
1039 grp = getgrgid(gid);
1040 if (grp) {
1041 return talloc_strdup(talloc_tos(), grp->gr_name);
1043 else {
1044 return talloc_asprintf(talloc_tos(),
1045 "%d",
1046 (int)gid);
1050 /*******************************************************************
1051 Convert a user name into a uid.
1052 ********************************************************************/
1054 uid_t nametouid(const char *name)
1056 struct passwd *pass;
1057 char *p;
1058 uid_t u;
1060 pass = Get_Pwnam_alloc(talloc_tos(), name);
1061 if (pass) {
1062 u = pass->pw_uid;
1063 TALLOC_FREE(pass);
1064 return u;
1067 u = (uid_t)strtol(name, &p, 0);
1068 if ((p != name) && (*p == '\0'))
1069 return u;
1071 return (uid_t)-1;
1074 /*******************************************************************
1075 Convert a name to a gid_t if possible. Return -1 if not a group.
1076 ********************************************************************/
1078 gid_t nametogid(const char *name)
1080 struct group *grp;
1081 char *p;
1082 gid_t g;
1084 g = (gid_t)strtol(name, &p, 0);
1085 if ((p != name) && (*p == '\0'))
1086 return g;
1088 grp = sys_getgrnam(name);
1089 if (grp)
1090 return(grp->gr_gid);
1091 return (gid_t)-1;
1094 /*******************************************************************
1095 Something really nasty happened - panic !
1096 ********************************************************************/
1098 void smb_panic(const char *const why)
1100 char *cmd;
1101 int result;
1103 #ifdef DEVELOPER
1106 if (global_clobber_region_function) {
1107 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1108 global_clobber_region_function,
1109 global_clobber_region_line));
1112 #endif
1114 DEBUG(0,("PANIC (pid %llu): %s\n",
1115 (unsigned long long)sys_getpid(), why));
1116 log_stack_trace();
1118 cmd = lp_panic_action();
1119 if (cmd && *cmd) {
1120 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1121 result = system(cmd);
1123 if (result == -1)
1124 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1125 strerror(errno)));
1126 else
1127 DEBUG(0, ("smb_panic(): action returned status %d\n",
1128 WEXITSTATUS(result)));
1131 dump_core();
1134 /*******************************************************************
1135 Print a backtrace of the stack to the debug log. This function
1136 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1137 exit shortly after calling it.
1138 ********************************************************************/
1140 #ifdef HAVE_LIBUNWIND_H
1141 #include <libunwind.h>
1142 #endif
1144 #ifdef HAVE_EXECINFO_H
1145 #include <execinfo.h>
1146 #endif
1148 #ifdef HAVE_LIBEXC_H
1149 #include <libexc.h>
1150 #endif
1152 void log_stack_trace(void)
1154 #ifdef HAVE_LIBUNWIND
1155 /* Try to use libunwind before any other technique since on ia64
1156 * libunwind correctly walks the stack in more circumstances than
1157 * backtrace.
1159 unw_cursor_t cursor;
1160 unw_context_t uc;
1161 unsigned i = 0;
1163 char procname[256];
1164 unw_word_t ip, sp, off;
1166 procname[sizeof(procname) - 1] = '\0';
1168 if (unw_getcontext(&uc) != 0) {
1169 goto libunwind_failed;
1172 if (unw_init_local(&cursor, &uc) != 0) {
1173 goto libunwind_failed;
1176 DEBUG(0, ("BACKTRACE:\n"));
1178 do {
1179 ip = sp = 0;
1180 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1181 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1183 switch (unw_get_proc_name(&cursor,
1184 procname, sizeof(procname) - 1, &off) ) {
1185 case 0:
1186 /* Name found. */
1187 case -UNW_ENOMEM:
1188 /* Name truncated. */
1189 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1190 i, procname, (long long)off,
1191 (long long)ip, (long long) sp));
1192 break;
1193 default:
1194 /* case -UNW_ENOINFO: */
1195 /* case -UNW_EUNSPEC: */
1196 /* No symbol name found. */
1197 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1198 i, "<unknown symbol>",
1199 (long long)ip, (long long) sp));
1201 ++i;
1202 } while (unw_step(&cursor) > 0);
1204 return;
1206 libunwind_failed:
1207 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1209 #elif HAVE_BACKTRACE_SYMBOLS
1210 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1211 size_t backtrace_size;
1212 char **backtrace_strings;
1214 /* get the backtrace (stack frames) */
1215 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1216 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1218 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1219 (unsigned long)backtrace_size));
1221 if (backtrace_strings) {
1222 int i;
1224 for (i = 0; i < backtrace_size; i++)
1225 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1227 /* Leak the backtrace_strings, rather than risk what free() might do */
1230 #elif HAVE_LIBEXC
1232 /* The IRIX libexc library provides an API for unwinding the stack. See
1233 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1234 * since we are about to abort anyway, it hardly matters.
1237 #define NAMESIZE 32 /* Arbitrary */
1239 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1240 char * names[BACKTRACE_STACK_SIZE];
1241 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1243 int i;
1244 int levels;
1246 ZERO_ARRAY(addrs);
1247 ZERO_ARRAY(names);
1248 ZERO_ARRAY(namebuf);
1250 /* We need to be root so we can open our /proc entry to walk
1251 * our stack. It also helps when we want to dump core.
1253 become_root();
1255 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1256 names[i] = namebuf + (i * NAMESIZE);
1259 levels = trace_back_stack(0, addrs, names,
1260 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1262 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1263 for (i = 0; i < levels; i++) {
1264 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1266 #undef NAMESIZE
1268 #else
1269 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1270 #endif
1273 /*******************************************************************
1274 A readdir wrapper which just returns the file name.
1275 ********************************************************************/
1277 const char *readdirname(SMB_STRUCT_DIR *p)
1279 SMB_STRUCT_DIRENT *ptr;
1280 char *dname;
1282 if (!p)
1283 return(NULL);
1285 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1286 if (!ptr)
1287 return(NULL);
1289 dname = ptr->d_name;
1291 #ifdef NEXT2
1292 if (telldir(p) < 0)
1293 return(NULL);
1294 #endif
1296 #ifdef HAVE_BROKEN_READDIR_NAME
1297 /* using /usr/ucb/cc is BAD */
1298 dname = dname - 2;
1299 #endif
1301 return talloc_strdup(talloc_tos(), dname);
1304 /*******************************************************************
1305 Utility function used to decide if the last component
1306 of a path matches a (possibly wildcarded) entry in a namelist.
1307 ********************************************************************/
1309 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1311 const char *last_component;
1313 /* if we have no list it's obviously not in the path */
1314 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1315 return False;
1318 DEBUG(8, ("is_in_path: %s\n", name));
1320 /* Get the last component of the unix name. */
1321 last_component = strrchr_m(name, '/');
1322 if (!last_component) {
1323 last_component = name;
1324 } else {
1325 last_component++; /* Go past '/' */
1328 for(; namelist->name != NULL; namelist++) {
1329 if(namelist->is_wild) {
1330 if (mask_match(last_component, namelist->name, case_sensitive)) {
1331 DEBUG(8,("is_in_path: mask match succeeded\n"));
1332 return True;
1334 } else {
1335 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1336 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1337 DEBUG(8,("is_in_path: match succeeded\n"));
1338 return True;
1342 DEBUG(8,("is_in_path: match not found\n"));
1343 return False;
1346 /*******************************************************************
1347 Strip a '/' separated list into an array of
1348 name_compare_enties structures suitable for
1349 passing to is_in_path(). We do this for
1350 speed so we can pre-parse all the names in the list
1351 and don't do it for each call to is_in_path().
1352 namelist is modified here and is assumed to be
1353 a copy owned by the caller.
1354 We also check if the entry contains a wildcard to
1355 remove a potentially expensive call to mask_match
1356 if possible.
1357 ********************************************************************/
1359 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
1361 char *name_end;
1362 char *nameptr = (char *)namelist;
1363 int num_entries = 0;
1364 int i;
1366 (*ppname_array) = NULL;
1368 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1369 return;
1371 /* We need to make two passes over the string. The
1372 first to count the number of elements, the second
1373 to split it.
1376 while(*nameptr) {
1377 if ( *nameptr == '/' ) {
1378 /* cope with multiple (useless) /s) */
1379 nameptr++;
1380 continue;
1382 /* anything left? */
1383 if ( *nameptr == '\0' )
1384 break;
1386 /* find the next '/' or consume remaining */
1387 name_end = strchr_m(nameptr, '/');
1388 if (name_end == NULL)
1389 name_end = (char *)nameptr + strlen(nameptr);
1391 /* next segment please */
1392 nameptr = name_end + 1;
1393 num_entries++;
1396 if(num_entries == 0)
1397 return;
1399 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1400 DEBUG(0,("set_namearray: malloc fail\n"));
1401 return;
1404 /* Now copy out the names */
1405 nameptr = (char *)namelist;
1406 i = 0;
1407 while(*nameptr) {
1408 if ( *nameptr == '/' ) {
1409 /* cope with multiple (useless) /s) */
1410 nameptr++;
1411 continue;
1413 /* anything left? */
1414 if ( *nameptr == '\0' )
1415 break;
1417 /* find the next '/' or consume remaining */
1418 name_end = strchr_m(nameptr, '/');
1419 if (name_end)
1420 *name_end = '\0';
1421 else
1422 name_end = nameptr + strlen(nameptr);
1424 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1425 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1426 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1427 return;
1430 /* next segment please */
1431 nameptr = name_end + 1;
1432 i++;
1435 (*ppname_array)[i].name = NULL;
1437 return;
1440 /****************************************************************************
1441 Routine to free a namearray.
1442 ****************************************************************************/
1444 void free_namearray(name_compare_entry *name_array)
1446 int i;
1448 if(name_array == NULL)
1449 return;
1451 for(i=0; name_array[i].name!=NULL; i++)
1452 SAFE_FREE(name_array[i].name);
1453 SAFE_FREE(name_array);
1456 #undef DBGC_CLASS
1457 #define DBGC_CLASS DBGC_LOCKING
1459 /****************************************************************************
1460 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1461 is dealt with in posix.c
1462 Returns True if we have information regarding this lock region (and returns
1463 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1464 ****************************************************************************/
1466 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1468 SMB_STRUCT_FLOCK lock;
1469 int ret;
1471 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1472 fd,(double)*poffset,(double)*pcount,*ptype));
1474 lock.l_type = *ptype;
1475 lock.l_whence = SEEK_SET;
1476 lock.l_start = *poffset;
1477 lock.l_len = *pcount;
1478 lock.l_pid = 0;
1480 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1482 if (ret == -1) {
1483 int sav = errno;
1484 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1485 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1486 errno = sav;
1487 return False;
1490 *ptype = lock.l_type;
1491 *poffset = lock.l_start;
1492 *pcount = lock.l_len;
1493 *ppid = lock.l_pid;
1495 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1496 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1497 return True;
1500 #undef DBGC_CLASS
1501 #define DBGC_CLASS DBGC_ALL
1503 /*******************************************************************
1504 Is the name specified one of my netbios names.
1505 Returns true if it is equal, false otherwise.
1506 ********************************************************************/
1508 bool is_myname(const char *s)
1510 int n;
1511 bool ret = False;
1513 for (n=0; my_netbios_names(n); n++) {
1514 if (strequal(my_netbios_names(n), s)) {
1515 ret=True;
1516 break;
1519 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1520 return(ret);
1523 /*******************************************************************
1524 Is the name specified our workgroup/domain.
1525 Returns true if it is equal, false otherwise.
1526 ********************************************************************/
1528 bool is_myworkgroup(const char *s)
1530 bool ret = False;
1532 if (strequal(s, lp_workgroup())) {
1533 ret=True;
1536 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1537 return(ret);
1540 /*******************************************************************
1541 we distinguish between 2K and XP by the "Native Lan Manager" string
1542 WinXP => "Windows 2002 5.1"
1543 WinXP 64bit => "Windows XP 5.2"
1544 Win2k => "Windows 2000 5.0"
1545 NT4 => "Windows NT 4.0"
1546 Win9x => "Windows 4.0"
1547 Windows 2003 doesn't set the native lan manager string but
1548 they do set the domain to "Windows 2003 5.2" (probably a bug).
1549 ********************************************************************/
1551 void ra_lanman_string( const char *native_lanman )
1553 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1554 set_remote_arch( RA_WINXP );
1555 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1556 set_remote_arch( RA_WINXP64 );
1557 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1558 set_remote_arch( RA_WIN2K3 );
1561 static const char *remote_arch_str;
1563 const char *get_remote_arch_str(void)
1565 if (!remote_arch_str) {
1566 return "UNKNOWN";
1568 return remote_arch_str;
1571 /*******************************************************************
1572 Set the horrid remote_arch string based on an enum.
1573 ********************************************************************/
1575 void set_remote_arch(enum remote_arch_types type)
1577 ra_type = type;
1578 switch( type ) {
1579 case RA_WFWG:
1580 remote_arch_str = "WfWg";
1581 break;
1582 case RA_OS2:
1583 remote_arch_str = "OS2";
1584 break;
1585 case RA_WIN95:
1586 remote_arch_str = "Win95";
1587 break;
1588 case RA_WINNT:
1589 remote_arch_str = "WinNT";
1590 break;
1591 case RA_WIN2K:
1592 remote_arch_str = "Win2K";
1593 break;
1594 case RA_WINXP:
1595 remote_arch_str = "WinXP";
1596 break;
1597 case RA_WINXP64:
1598 remote_arch_str = "WinXP64";
1599 break;
1600 case RA_WIN2K3:
1601 remote_arch_str = "Win2K3";
1602 break;
1603 case RA_VISTA:
1604 remote_arch_str = "Vista";
1605 break;
1606 case RA_SAMBA:
1607 remote_arch_str = "Samba";
1608 break;
1609 case RA_CIFSFS:
1610 remote_arch_str = "CIFSFS";
1611 break;
1612 case RA_OSX:
1613 remote_arch_str = "OSX";
1614 break;
1615 default:
1616 ra_type = RA_UNKNOWN;
1617 remote_arch_str = "UNKNOWN";
1618 break;
1621 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1622 remote_arch_str));
1625 /*******************************************************************
1626 Get the remote_arch type.
1627 ********************************************************************/
1629 enum remote_arch_types get_remote_arch(void)
1631 return ra_type;
1634 const char *tab_depth(int level, int depth)
1636 if( CHECK_DEBUGLVL(level) ) {
1637 dbgtext("%*s", depth*4, "");
1639 return "";
1642 /*****************************************************************************
1643 Provide a checksum on a string
1645 Input: s - the null-terminated character string for which the checksum
1646 will be calculated.
1648 Output: The checksum value calculated for s.
1649 *****************************************************************************/
1651 int str_checksum(const char *s)
1653 TDB_DATA key = string_tdb_data(s);
1654 return tdb_jenkins_hash(&key);
1657 /*****************************************************************
1658 Zero a memory area then free it. Used to catch bugs faster.
1659 *****************************************************************/
1661 void zero_free(void *p, size_t size)
1663 memset(p, 0, size);
1664 SAFE_FREE(p);
1667 /*****************************************************************
1668 Set our open file limit to a requested max and return the limit.
1669 *****************************************************************/
1671 int set_maxfiles(int requested_max)
1673 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1674 struct rlimit rlp;
1675 int saved_current_limit;
1677 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1678 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1679 strerror(errno) ));
1680 /* just guess... */
1681 return requested_max;
1685 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1686 * account for the extra fd we need
1687 * as well as the log files and standard
1688 * handles etc. Save the limit we want to set in case
1689 * we are running on an OS that doesn't support this limit (AIX)
1690 * which always returns RLIM_INFINITY for rlp.rlim_max.
1693 /* Try raising the hard (max) limit to the requested amount. */
1695 #if defined(RLIM_INFINITY)
1696 if (rlp.rlim_max != RLIM_INFINITY) {
1697 int orig_max = rlp.rlim_max;
1699 if ( rlp.rlim_max < requested_max )
1700 rlp.rlim_max = requested_max;
1702 /* This failing is not an error - many systems (Linux) don't
1703 support our default request of 10,000 open files. JRA. */
1705 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1706 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1707 (int)rlp.rlim_max, strerror(errno) ));
1709 /* Set failed - restore original value from get. */
1710 rlp.rlim_max = orig_max;
1713 #endif
1715 /* Now try setting the soft (current) limit. */
1717 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1719 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1720 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1721 (int)rlp.rlim_cur, strerror(errno) ));
1722 /* just guess... */
1723 return saved_current_limit;
1726 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1727 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1728 strerror(errno) ));
1729 /* just guess... */
1730 return saved_current_limit;
1733 #if defined(RLIM_INFINITY)
1734 if(rlp.rlim_cur == RLIM_INFINITY)
1735 return saved_current_limit;
1736 #endif
1738 if((int)rlp.rlim_cur > saved_current_limit)
1739 return saved_current_limit;
1741 return rlp.rlim_cur;
1742 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1744 * No way to know - just guess...
1746 return requested_max;
1747 #endif
1750 /*****************************************************************
1751 malloc that aborts with smb_panic on fail or zero size.
1752 *****************************************************************/
1754 void *smb_xmalloc_array(size_t size, unsigned int count)
1756 void *p;
1757 if (size == 0) {
1758 smb_panic("smb_xmalloc_array: called with zero size");
1760 if (count >= MAX_ALLOC_SIZE/size) {
1761 smb_panic("smb_xmalloc_array: alloc size too large");
1763 if ((p = SMB_MALLOC(size*count)) == NULL) {
1764 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
1765 (unsigned long)size, (unsigned long)count));
1766 smb_panic("smb_xmalloc_array: malloc failed");
1768 return p;
1772 vasprintf that aborts on malloc fail
1775 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
1777 int n;
1778 va_list ap2;
1780 va_copy(ap2, ap);
1782 n = vasprintf(ptr, format, ap2);
1783 va_end(ap2);
1784 if (n == -1 || ! *ptr) {
1785 smb_panic("smb_xvasprintf: out of memory");
1787 return n;
1790 /*****************************************************************
1791 Get local hostname and cache result.
1792 *****************************************************************/
1794 char *myhostname(void)
1796 static char *ret;
1797 if (ret == NULL) {
1798 ret = get_myname(NULL);
1800 return ret;
1804 * @brief Returns an absolute path to a file concatenating the provided
1805 * @a rootpath and @a basename
1807 * @param name Filename, relative to @a rootpath
1809 * @retval Pointer to a string containing the full path.
1812 static char *xx_path(const char *name, const char *rootpath)
1814 char *fname = NULL;
1816 fname = talloc_strdup(talloc_tos(), rootpath);
1817 if (!fname) {
1818 return NULL;
1820 trim_string(fname,"","/");
1822 if (!directory_exist(fname)) {
1823 if (!mkdir(fname,0755))
1824 DEBUG(1, ("Unable to create directory %s for file %s. "
1825 "Error was %s\n", fname, name, strerror(errno)));
1828 return talloc_asprintf(talloc_tos(),
1829 "%s/%s",
1830 fname,
1831 name);
1835 * @brief Returns an absolute path to a file in the Samba lock directory.
1837 * @param name File to find, relative to LOCKDIR.
1839 * @retval Pointer to a talloc'ed string containing the full path.
1842 char *lock_path(const char *name)
1844 return xx_path(name, lp_lockdir());
1848 * @brief Returns an absolute path to a file in the Samba pid directory.
1850 * @param name File to find, relative to PIDDIR.
1852 * @retval Pointer to a talloc'ed string containing the full path.
1855 char *pid_path(const char *name)
1857 return xx_path(name, lp_piddir());
1861 * @brief Returns an absolute path to a file in the Samba lib directory.
1863 * @param name File to find, relative to LIBDIR.
1865 * @retval Pointer to a string containing the full path.
1868 char *lib_path(const char *name)
1870 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
1874 * @brief Returns an absolute path to a file in the Samba modules directory.
1876 * @param name File to find, relative to MODULESDIR.
1878 * @retval Pointer to a string containing the full path.
1881 char *modules_path(const char *name)
1883 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
1887 * @brief Returns an absolute path to a file in the Samba data directory.
1889 * @param name File to find, relative to CODEPAGEDIR.
1891 * @retval Pointer to a talloc'ed string containing the full path.
1894 char *data_path(const char *name)
1896 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
1900 * @brief Returns an absolute path to a file in the Samba state directory.
1902 * @param name File to find, relative to STATEDIR.
1904 * @retval Pointer to a talloc'ed string containing the full path.
1907 char *state_path(const char *name)
1909 return xx_path(name, lp_statedir());
1913 * @brief Returns an absolute path to a file in the Samba cache directory.
1915 * @param name File to find, relative to CACHEDIR.
1917 * @retval Pointer to a talloc'ed string containing the full path.
1920 char *cache_path(const char *name)
1922 return xx_path(name, lp_cachedir());
1926 * @brief Returns the platform specific shared library extension.
1928 * @retval Pointer to a const char * containing the extension.
1931 const char *shlib_ext(void)
1933 return get_dyn_SHLIBEXT();
1936 /*******************************************************************
1937 Given a filename - get its directory name
1938 ********************************************************************/
1940 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
1941 const char **name)
1943 char *p;
1944 ptrdiff_t len;
1946 p = strrchr_m(dir, '/'); /* Find final '/', if any */
1948 if (p == NULL) {
1949 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
1950 return False;
1952 if (name) {
1953 *name = dir;
1955 return True;
1958 len = p-dir;
1960 if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
1961 return False;
1963 (*parent)[len] = '\0';
1965 if (name) {
1966 *name = p+1;
1968 return True;
1971 /*******************************************************************
1972 Determine if a pattern contains any Microsoft wildcard characters.
1973 *******************************************************************/
1975 bool ms_has_wild(const char *s)
1977 char c;
1979 if (lp_posix_pathnames()) {
1980 /* With posix pathnames no characters are wild. */
1981 return False;
1984 while ((c = *s++)) {
1985 switch (c) {
1986 case '*':
1987 case '?':
1988 case '<':
1989 case '>':
1990 case '"':
1991 return True;
1994 return False;
1997 bool ms_has_wild_w(const smb_ucs2_t *s)
1999 smb_ucs2_t c;
2000 if (!s) return False;
2001 while ((c = *s++)) {
2002 switch (c) {
2003 case UCS2_CHAR('*'):
2004 case UCS2_CHAR('?'):
2005 case UCS2_CHAR('<'):
2006 case UCS2_CHAR('>'):
2007 case UCS2_CHAR('"'):
2008 return True;
2011 return False;
2014 /*******************************************************************
2015 A wrapper that handles case sensitivity and the special handling
2016 of the ".." name.
2017 *******************************************************************/
2019 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2021 if (ISDOTDOT(string))
2022 string = ".";
2023 if (ISDOT(pattern))
2024 return False;
2026 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2029 /*******************************************************************
2030 A wrapper that handles case sensitivity and the special handling
2031 of the ".." name. Varient that is only called by old search code which requires
2032 pattern translation.
2033 *******************************************************************/
2035 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2037 if (ISDOTDOT(string))
2038 string = ".";
2039 if (ISDOT(pattern))
2040 return False;
2042 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2045 /*******************************************************************
2046 A wrapper that handles a list of patters and calls mask_match()
2047 on each. Returns True if any of the patterns match.
2048 *******************************************************************/
2050 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2052 while (listLen-- > 0) {
2053 if (mask_match(string, *list++, is_case_sensitive))
2054 return True;
2056 return False;
2059 /*********************************************************
2060 Recursive routine that is called by unix_wild_match.
2061 *********************************************************/
2063 static bool unix_do_match(const char *regexp, const char *str)
2065 const char *p;
2067 for( p = regexp; *p && *str; ) {
2069 switch(*p) {
2070 case '?':
2071 str++;
2072 p++;
2073 break;
2075 case '*':
2078 * Look for a character matching
2079 * the one after the '*'.
2081 p++;
2082 if(!*p)
2083 return true; /* Automatic match */
2084 while(*str) {
2086 while(*str && (*p != *str))
2087 str++;
2090 * Patch from weidel@multichart.de. In the case of the regexp
2091 * '*XX*' we want to ensure there are at least 2 'X' characters
2092 * in the string after the '*' for a match to be made.
2096 int matchcount=0;
2099 * Eat all the characters that match, but count how many there were.
2102 while(*str && (*p == *str)) {
2103 str++;
2104 matchcount++;
2108 * Now check that if the regexp had n identical characters that
2109 * matchcount had at least that many matches.
2112 while ( *(p+1) && (*(p+1) == *p)) {
2113 p++;
2114 matchcount--;
2117 if ( matchcount <= 0 )
2118 return false;
2121 str--; /* We've eaten the match char after the '*' */
2123 if(unix_do_match(p, str))
2124 return true;
2126 if(!*str)
2127 return false;
2128 else
2129 str++;
2131 return false;
2133 default:
2134 if(*str != *p)
2135 return false;
2136 str++;
2137 p++;
2138 break;
2142 if(!*p && !*str)
2143 return true;
2145 if (!*p && str[0] == '.' && str[1] == 0)
2146 return true;
2148 if (!*str && *p == '?') {
2149 while (*p == '?')
2150 p++;
2151 return(!*p);
2154 if(!*str && (*p == '*' && p[1] == '\0'))
2155 return true;
2157 return false;
2160 /*******************************************************************
2161 Simple case insensitive interface to a UNIX wildcard matcher.
2162 Returns True if match, False if not.
2163 *******************************************************************/
2165 bool unix_wild_match(const char *pattern, const char *string)
2167 TALLOC_CTX *ctx = talloc_stackframe();
2168 char *p2;
2169 char *s2;
2170 char *p;
2171 bool ret = false;
2173 p2 = talloc_strdup(ctx,pattern);
2174 s2 = talloc_strdup(ctx,string);
2175 if (!p2 || !s2) {
2176 TALLOC_FREE(ctx);
2177 return false;
2179 strlower_m(p2);
2180 strlower_m(s2);
2182 /* Remove any *? and ** from the pattern as they are meaningless */
2183 for(p = p2; *p; p++) {
2184 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2185 memmove(&p[1], &p[2], strlen(&p[2])+1);
2189 if (strequal(p2,"*")) {
2190 TALLOC_FREE(ctx);
2191 return true;
2194 ret = unix_do_match(p2, s2);
2195 TALLOC_FREE(ctx);
2196 return ret;
2199 /**********************************************************************
2200 Converts a name to a fully qualified domain name.
2201 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2202 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2203 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2204 ***********************************************************************/
2206 bool name_to_fqdn(fstring fqdn, const char *name)
2208 char *full = NULL;
2209 struct hostent *hp = gethostbyname(name);
2211 if (!hp || !hp->h_name || !*hp->h_name) {
2212 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2213 fstrcpy(fqdn, name);
2214 return false;
2217 /* Find out if the fqdn is returned as an alias
2218 * to cope with /etc/hosts files where the first
2219 * name is not the fqdn but the short name */
2220 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2221 int i;
2222 for (i = 0; hp->h_aliases[i]; i++) {
2223 if (strchr_m(hp->h_aliases[i], '.')) {
2224 full = hp->h_aliases[i];
2225 break;
2229 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2230 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2231 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2232 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2233 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2234 full = hp->h_name;
2236 if (!full) {
2237 full = hp->h_name;
2240 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2241 fstrcpy(fqdn, full);
2242 return true;
2245 /**********************************************************************
2246 Append a DATA_BLOB to a talloc'ed object
2247 ***********************************************************************/
2249 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
2251 size_t old_size = 0;
2252 char *result;
2254 if (blob.length == 0) {
2255 return buf;
2258 if (buf != NULL) {
2259 old_size = talloc_get_size(buf);
2262 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
2263 if (result == NULL) {
2264 return NULL;
2267 memcpy(result + old_size, blob.data, blob.length);
2268 return result;
2271 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2273 switch (share_access & ~FILE_SHARE_DELETE) {
2274 case FILE_SHARE_NONE:
2275 return DENY_ALL;
2276 case FILE_SHARE_READ:
2277 return DENY_WRITE;
2278 case FILE_SHARE_WRITE:
2279 return DENY_READ;
2280 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2281 return DENY_NONE;
2283 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2284 return DENY_DOS;
2285 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2286 return DENY_FCB;
2289 return (uint32)-1;
2292 pid_t procid_to_pid(const struct server_id *proc)
2294 return proc->pid;
2297 static uint32 my_vnn = NONCLUSTER_VNN;
2299 void set_my_vnn(uint32 vnn)
2301 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2302 my_vnn = vnn;
2305 uint32 get_my_vnn(void)
2307 return my_vnn;
2310 static uint64_t my_unique_id = 0;
2312 void set_my_unique_id(uint64_t unique_id)
2314 my_unique_id = unique_id;
2317 struct server_id pid_to_procid(pid_t pid)
2319 struct server_id result;
2320 result.pid = pid;
2321 result.unique_id = my_unique_id;
2322 result.vnn = my_vnn;
2323 return result;
2326 struct server_id procid_self(void)
2328 return pid_to_procid(sys_getpid());
2331 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2333 if (p1->pid != p2->pid)
2334 return False;
2335 if (p1->vnn != p2->vnn)
2336 return False;
2337 return True;
2340 bool cluster_id_equal(const struct server_id *id1,
2341 const struct server_id *id2)
2343 return procid_equal(id1, id2);
2346 bool procid_is_me(const struct server_id *pid)
2348 if (pid->pid != sys_getpid())
2349 return False;
2350 if (pid->vnn != my_vnn)
2351 return False;
2352 return True;
2355 struct server_id interpret_pid(const char *pid_string)
2357 struct server_id result;
2358 int pid;
2359 unsigned int vnn;
2360 if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
2361 result.vnn = vnn;
2362 result.pid = pid;
2364 else if (sscanf(pid_string, "%d", &pid) == 1) {
2365 result.vnn = get_my_vnn();
2366 result.pid = pid;
2368 else {
2369 result.vnn = NONCLUSTER_VNN;
2370 result.pid = -1;
2372 /* Assigning to result.pid may have overflowed
2373 Map negative pid to -1: i.e. error */
2374 if (result.pid < 0) {
2375 result.pid = -1;
2377 result.unique_id = 0;
2378 return result;
2381 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2383 if (pid->vnn == NONCLUSTER_VNN) {
2384 return talloc_asprintf(mem_ctx,
2385 "%d",
2386 (int)pid->pid);
2388 else {
2389 return talloc_asprintf(mem_ctx,
2390 "%u:%d",
2391 (unsigned)pid->vnn,
2392 (int)pid->pid);
2396 char *procid_str_static(const struct server_id *pid)
2398 return procid_str(talloc_tos(), pid);
2401 bool procid_valid(const struct server_id *pid)
2403 return (pid->pid != -1);
2406 bool procid_is_local(const struct server_id *pid)
2408 return pid->vnn == my_vnn;
2411 /****************************************************************
2412 Check if offset/length fit into bufsize. Should probably be
2413 merged with is_offset_safe, but this would require a rewrite
2414 of lanman.c. Later :-)
2415 ****************************************************************/
2417 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2419 if ((offset + length < offset) || (offset + length < length)) {
2420 /* wrap */
2421 return true;
2423 if ((offset > bufsize) || (offset + length > bufsize)) {
2424 /* overflow */
2425 return true;
2427 return false;
2430 /****************************************************************
2431 Check if an offset into a buffer is safe.
2432 If this returns True it's safe to indirect into the byte at
2433 pointer ptr+off.
2434 ****************************************************************/
2436 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2438 const char *end_base = buf_base + buf_len;
2439 char *end_ptr = ptr + off;
2441 if (!buf_base || !ptr) {
2442 return False;
2445 if (end_base < buf_base || end_ptr < ptr) {
2446 return False; /* wrap. */
2449 if (end_ptr < end_base) {
2450 return True;
2452 return False;
2455 /****************************************************************
2456 Return a safe pointer into a buffer, or NULL.
2457 ****************************************************************/
2459 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2461 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2462 ptr + off : NULL;
2465 /****************************************************************
2466 Return a safe pointer into a string within a buffer, or NULL.
2467 ****************************************************************/
2469 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2471 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2472 return NULL;
2474 /* Check if a valid string exists at this offset. */
2475 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2476 return NULL;
2478 return ptr + off;
2481 /****************************************************************
2482 Return an SVAL at a pointer, or failval if beyond the end.
2483 ****************************************************************/
2485 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2488 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2489 * NOT ptr[2].
2491 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2492 return failval;
2494 return SVAL(ptr,off);
2497 /****************************************************************
2498 Return an IVAL at a pointer, or failval if beyond the end.
2499 ****************************************************************/
2501 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2504 * Note we use off+3 here, not off+4 as IVAL accesses
2505 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2507 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2508 return failval;
2510 return IVAL(ptr,off);
2513 /****************************************************************
2514 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2515 call (they take care of winbind separator and other winbind specific settings).
2516 ****************************************************************/
2518 void split_domain_user(TALLOC_CTX *mem_ctx,
2519 const char *full_name,
2520 char **domain,
2521 char **user)
2523 const char *p = NULL;
2525 p = strchr_m(full_name, '\\');
2527 if (p != NULL) {
2528 *domain = talloc_strndup(mem_ctx, full_name,
2529 PTR_DIFF(p, full_name));
2530 *user = talloc_strdup(mem_ctx, p+1);
2531 } else {
2532 *domain = talloc_strdup(mem_ctx, "");
2533 *user = talloc_strdup(mem_ctx, full_name);
2537 #if 0
2539 Disable these now we have checked all code paths and ensured
2540 NULL returns on zero request. JRA.
2542 /****************************************************************
2543 talloc wrapper functions that guarentee a null pointer return
2544 if size == 0.
2545 ****************************************************************/
2547 #ifndef MAX_TALLOC_SIZE
2548 #define MAX_TALLOC_SIZE 0x10000000
2549 #endif
2552 * talloc and zero memory.
2553 * - returns NULL if size is zero.
2556 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2558 void *p;
2560 if (size == 0) {
2561 return NULL;
2564 p = talloc_named_const(ctx, size, name);
2566 if (p) {
2567 memset(p, '\0', size);
2570 return p;
2574 * memdup with a talloc.
2575 * - returns NULL if size is zero.
2578 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
2580 void *newp;
2582 if (size == 0) {
2583 return NULL;
2586 newp = talloc_named_const(t, size, name);
2587 if (newp) {
2588 memcpy(newp, p, size);
2591 return newp;
2595 * alloc an array, checking for integer overflow in the array size.
2596 * - returns NULL if count or el_size are zero.
2599 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2601 if (count >= MAX_TALLOC_SIZE/el_size) {
2602 return NULL;
2605 if (el_size == 0 || count == 0) {
2606 return NULL;
2609 return talloc_named_const(ctx, el_size * count, name);
2613 * alloc an zero array, checking for integer overflow in the array size
2614 * - returns NULL if count or el_size are zero.
2617 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2619 if (count >= MAX_TALLOC_SIZE/el_size) {
2620 return NULL;
2623 if (el_size == 0 || count == 0) {
2624 return NULL;
2627 return _talloc_zero(ctx, el_size * count, name);
2631 * Talloc wrapper that returns NULL if size == 0.
2633 void *talloc_zeronull(const void *context, size_t size, const char *name)
2635 if (size == 0) {
2636 return NULL;
2638 return talloc_named_const(context, size, name);
2640 #endif
2642 /****************************************************************
2643 strip off leading '\\' from a hostname
2644 ****************************************************************/
2646 const char *strip_hostname(const char *s)
2648 if (!s) {
2649 return NULL;
2652 if (strlen_m(s) < 3) {
2653 return s;
2656 if (s[0] == '\\') s++;
2657 if (s[0] == '\\') s++;
2659 return s;
2662 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2663 struct tevent_context *ev,
2664 NTSTATUS *status)
2666 bool ret = tevent_req_poll(req, ev);
2667 if (!ret) {
2668 *status = map_nt_error_from_unix(errno);
2670 return ret;
2673 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2675 if (!NT_STATUS_IS_OK(err1)) {
2676 *result = err1;
2677 return true;
2679 if (!NT_STATUS_IS_OK(err2)) {
2680 *result = err2;
2681 return true;
2683 return false;
2686 int timeval_to_msec(struct timeval t)
2688 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;