s3-messages: only include messages.h where needed.
[Samba/gbeck.git] / source3 / lib / util.c
blob99823db2fee24c11cae3a243fb7b358378f59cce
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 "popt_common.h"
28 #include "secrets.h"
29 #include "ctdbd_conn.h"
30 #include "../lib/util/util_pw.h"
31 #include "messages.h"
33 extern char *global_clobber_region_function;
34 extern unsigned int global_clobber_region_line;
36 /* Max allowable allococation - 256mb - 0x10000000 */
37 #define MAX_ALLOC_SIZE (1024*1024*256)
39 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
40 #ifdef WITH_NISPLUS_HOME
41 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
43 * The following lines are needed due to buggy include files
44 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
45 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
46 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
47 * an enum in /usr/include/rpcsvc/nis.h.
50 #if defined(GROUP)
51 #undef GROUP
52 #endif
54 #if defined(GROUP_OBJ)
55 #undef GROUP_OBJ
56 #endif
58 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
60 #include <rpcsvc/nis.h>
62 #endif /* WITH_NISPLUS_HOME */
63 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
65 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
67 enum protocol_types get_Protocol(void)
69 return Protocol;
72 void set_Protocol(enum protocol_types p)
74 Protocol = p;
77 static enum remote_arch_types ra_type = RA_UNKNOWN;
79 /***********************************************************************
80 Definitions for all names.
81 ***********************************************************************/
83 static char *smb_scope;
84 static int smb_num_netbios_names;
85 static char **smb_my_netbios_names;
87 /***********************************************************************
88 Allocate and set scope. Ensure upper case.
89 ***********************************************************************/
91 bool set_global_scope(const char *scope)
93 SAFE_FREE(smb_scope);
94 smb_scope = SMB_STRDUP(scope);
95 if (!smb_scope)
96 return False;
97 strupper_m(smb_scope);
98 return True;
101 /*********************************************************************
102 Ensure scope is never null string.
103 *********************************************************************/
105 const char *global_scope(void)
107 if (!smb_scope)
108 set_global_scope("");
109 return smb_scope;
112 static void free_netbios_names_array(void)
114 int i;
116 for (i = 0; i < smb_num_netbios_names; i++)
117 SAFE_FREE(smb_my_netbios_names[i]);
119 SAFE_FREE(smb_my_netbios_names);
120 smb_num_netbios_names = 0;
123 static bool allocate_my_netbios_names_array(size_t number)
125 free_netbios_names_array();
127 smb_num_netbios_names = number + 1;
128 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
130 if (!smb_my_netbios_names)
131 return False;
133 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
134 return True;
137 static bool set_my_netbios_names(const char *name, int i)
139 SAFE_FREE(smb_my_netbios_names[i]);
141 smb_my_netbios_names[i] = SMB_STRDUP(name);
142 if (!smb_my_netbios_names[i])
143 return False;
144 strupper_m(smb_my_netbios_names[i]);
145 return True;
148 /***********************************************************************
149 Free memory allocated to global objects
150 ***********************************************************************/
152 void gfree_names(void)
154 gfree_netbios_names();
155 SAFE_FREE( smb_scope );
156 free_netbios_names_array();
157 free_local_machine_name();
160 void gfree_all( void )
162 gfree_names();
163 gfree_loadparm();
164 gfree_case_tables();
165 gfree_charcnv();
166 gfree_interfaces();
167 gfree_debugsyms();
170 const char *my_netbios_names(int i)
172 return smb_my_netbios_names[i];
175 bool set_netbios_aliases(const char **str_array)
177 size_t namecount;
179 /* Work out the max number of netbios aliases that we have */
180 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
183 if ( global_myname() && *global_myname())
184 namecount++;
186 /* Allocate space for the netbios aliases */
187 if (!allocate_my_netbios_names_array(namecount))
188 return False;
190 /* Use the global_myname string first */
191 namecount=0;
192 if ( global_myname() && *global_myname()) {
193 set_my_netbios_names( global_myname(), namecount );
194 namecount++;
197 if (str_array) {
198 size_t i;
199 for ( i = 0; str_array[i] != NULL; i++) {
200 size_t n;
201 bool duplicate = False;
203 /* Look for duplicates */
204 for( n=0; n<namecount; n++ ) {
205 if( strequal( str_array[i], my_netbios_names(n) ) ) {
206 duplicate = True;
207 break;
210 if (!duplicate) {
211 if (!set_my_netbios_names(str_array[i], namecount))
212 return False;
213 namecount++;
217 return True;
220 /****************************************************************************
221 Common name initialization code.
222 ****************************************************************************/
224 bool init_names(void)
226 int n;
228 if (global_myname() == NULL || *global_myname() == '\0') {
229 if (!set_global_myname(myhostname())) {
230 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
231 return False;
235 if (!set_netbios_aliases(lp_netbios_aliases())) {
236 DEBUG( 0, ( "init_names: malloc fail.\n" ) );
237 return False;
240 set_local_machine_name(global_myname(),false);
242 DEBUG( 5, ("Netbios name list:-\n") );
243 for( n=0; my_netbios_names(n); n++ ) {
244 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
245 n, my_netbios_names(n) ) );
248 return( True );
251 /**************************************************************************n
252 Code to cope with username/password auth options from the commandline.
253 Used mainly in client tools.
254 ****************************************************************************/
256 struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
258 struct user_auth_info *result;
260 result = TALLOC_ZERO_P(mem_ctx, struct user_auth_info);
261 if (result == NULL) {
262 return NULL;
265 result->signing_state = Undefined;
266 return result;
269 const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info)
271 if (!auth_info->username) {
272 return "";
274 return auth_info->username;
277 void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
278 const char *username)
280 TALLOC_FREE(auth_info->username);
281 auth_info->username = talloc_strdup(auth_info, username);
282 if (!auth_info->username) {
283 exit(ENOMEM);
287 const char *get_cmdline_auth_info_domain(const struct user_auth_info *auth_info)
289 if (!auth_info->domain) {
290 return "";
292 return auth_info->domain;
295 void set_cmdline_auth_info_domain(struct user_auth_info *auth_info,
296 const char *domain)
298 TALLOC_FREE(auth_info->domain);
299 auth_info->domain = talloc_strdup(auth_info, domain);
300 if (!auth_info->domain) {
301 exit(ENOMEM);
305 const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info)
307 if (!auth_info->password) {
308 return "";
310 return auth_info->password;
313 void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
314 const char *password)
316 TALLOC_FREE(auth_info->password);
317 if (password == NULL) {
318 password = "";
320 auth_info->password = talloc_strdup(auth_info, password);
321 if (!auth_info->password) {
322 exit(ENOMEM);
324 auth_info->got_pass = true;
327 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
328 const char *arg)
330 auth_info->signing_state = -1;
331 if (strequal(arg, "off") || strequal(arg, "no") ||
332 strequal(arg, "false")) {
333 auth_info->signing_state = false;
334 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
335 strequal(arg, "true") || strequal(arg, "auto")) {
336 auth_info->signing_state = true;
337 } else if (strequal(arg, "force") || strequal(arg, "required") ||
338 strequal(arg, "forced")) {
339 auth_info->signing_state = Required;
340 } else {
341 return false;
343 return true;
346 int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
348 return auth_info->signing_state;
351 void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b)
353 auth_info->use_ccache = b;
356 bool get_cmdline_auth_info_use_ccache(const struct user_auth_info *auth_info)
358 return auth_info->use_ccache;
361 void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
362 bool b)
364 auth_info->use_kerberos = b;
367 bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info)
369 return auth_info->use_kerberos;
372 void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info,
373 bool b)
375 auth_info->fallback_after_kerberos = b;
378 bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info)
380 return auth_info->fallback_after_kerberos;
383 /* This should only be used by lib/popt_common.c JRA */
384 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
386 auth_info->use_kerberos = true;
387 auth_info->got_pass = true;
390 /* This should only be used by lib/popt_common.c JRA */
391 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
393 auth_info->smb_encrypt = true;
396 void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
398 auth_info->use_machine_account = true;
401 bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info)
403 return auth_info->got_pass;
406 bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info)
408 return auth_info->smb_encrypt;
411 bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info)
413 return auth_info->use_machine_account;
416 struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
417 const struct user_auth_info *src)
419 struct user_auth_info *result;
421 result = user_auth_info_init(mem_ctx);
422 if (result == NULL) {
423 return NULL;
426 *result = *src;
428 result->username = talloc_strdup(
429 result, get_cmdline_auth_info_username(src));
430 result->password = talloc_strdup(
431 result, get_cmdline_auth_info_password(src));
432 if ((result->username == NULL) || (result->password == NULL)) {
433 TALLOC_FREE(result);
434 return NULL;
437 return result;
440 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info)
442 char *pass = NULL;
443 char *account = NULL;
445 if (!get_cmdline_auth_info_use_machine_account(auth_info)) {
446 return false;
449 if (!secrets_init()) {
450 d_printf("ERROR: Unable to open secrets database\n");
451 return false;
454 if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
455 return false;
458 pass = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
459 if (!pass) {
460 d_printf("ERROR: Unable to fetch machine password for "
461 "%s in domain %s\n",
462 account, lp_workgroup());
463 SAFE_FREE(account);
464 return false;
467 set_cmdline_auth_info_username(auth_info, account);
468 set_cmdline_auth_info_password(auth_info, pass);
470 SAFE_FREE(account);
471 SAFE_FREE(pass);
473 return true;
476 /****************************************************************************
477 Ensure we have a password if one not given.
478 ****************************************************************************/
480 void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info)
482 char *label = NULL;
483 char *pass;
484 TALLOC_CTX *frame;
486 if (get_cmdline_auth_info_got_pass(auth_info) ||
487 get_cmdline_auth_info_use_kerberos(auth_info)) {
488 /* Already got one... */
489 return;
492 frame = talloc_stackframe();
493 label = talloc_asprintf(frame, "Enter %s's password: ",
494 get_cmdline_auth_info_username(auth_info));
495 pass = getpass(label);
496 if (pass) {
497 set_cmdline_auth_info_password(auth_info, pass);
499 TALLOC_FREE(frame);
502 /*******************************************************************
503 Check if a file exists - call vfs_file_exist for samba files.
504 ********************************************************************/
506 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
507 bool fake_dir_create_times)
509 SMB_STRUCT_STAT st;
510 if (!sbuf)
511 sbuf = &st;
513 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
514 return(False);
516 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
519 /*******************************************************************
520 Check if a unix domain socket exists - call vfs_file_exist for samba files.
521 ********************************************************************/
523 bool socket_exist(const char *fname)
525 SMB_STRUCT_STAT st;
526 if (sys_stat(fname, &st, false) != 0)
527 return(False);
529 return S_ISSOCK(st.st_ex_mode);
532 /*******************************************************************
533 Returns the size in bytes of the named given the stat struct.
534 ********************************************************************/
536 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
538 return sbuf->st_ex_size;
541 /*******************************************************************
542 Returns the size in bytes of the named file.
543 ********************************************************************/
545 SMB_OFF_T get_file_size(char *file_name)
547 SMB_STRUCT_STAT buf;
548 buf.st_ex_size = 0;
549 if (sys_stat(file_name, &buf, false) != 0)
550 return (SMB_OFF_T)-1;
551 return get_file_size_stat(&buf);
554 /*******************************************************************
555 Return a string representing an attribute for a file.
556 ********************************************************************/
558 char *attrib_string(uint16 mode)
560 fstring attrstr;
562 attrstr[0] = 0;
564 if (mode & aVOLID) fstrcat(attrstr,"V");
565 if (mode & aDIR) fstrcat(attrstr,"D");
566 if (mode & aARCH) fstrcat(attrstr,"A");
567 if (mode & aHIDDEN) fstrcat(attrstr,"H");
568 if (mode & aSYSTEM) fstrcat(attrstr,"S");
569 if (mode & aRONLY) fstrcat(attrstr,"R");
571 return talloc_strdup(talloc_tos(), attrstr);
574 /*******************************************************************
575 Show a smb message structure.
576 ********************************************************************/
578 void show_msg(char *buf)
580 int i;
581 int bcc=0;
583 if (!DEBUGLVL(5))
584 return;
586 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
587 smb_len(buf),
588 (int)CVAL(buf,smb_com),
589 (int)CVAL(buf,smb_rcls),
590 (int)CVAL(buf,smb_reh),
591 (int)SVAL(buf,smb_err),
592 (int)CVAL(buf,smb_flg),
593 (int)SVAL(buf,smb_flg2)));
594 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
595 (int)SVAL(buf,smb_tid),
596 (int)SVAL(buf,smb_pid),
597 (int)SVAL(buf,smb_uid),
598 (int)SVAL(buf,smb_mid)));
599 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
601 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
602 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
603 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
605 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
607 DEBUGADD(5,("smb_bcc=%d\n",bcc));
609 if (DEBUGLEVEL < 10)
610 return;
612 if (DEBUGLEVEL < 50)
613 bcc = MIN(bcc, 512);
615 dump_data(10, (uint8 *)smb_buf(buf), bcc);
618 /*******************************************************************
619 Set the length and marker of an encrypted smb packet.
620 ********************************************************************/
622 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
624 _smb_setlen(buf,len);
626 SCVAL(buf,4,0xFF);
627 SCVAL(buf,5,'E');
628 SSVAL(buf,6,enc_ctx_num);
631 /*******************************************************************
632 Set the length and marker of an smb packet.
633 ********************************************************************/
635 void smb_setlen(char *buf,int len)
637 _smb_setlen(buf,len);
639 SCVAL(buf,4,0xFF);
640 SCVAL(buf,5,'S');
641 SCVAL(buf,6,'M');
642 SCVAL(buf,7,'B');
645 /*******************************************************************
646 Setup only the byte count for a smb message.
647 ********************************************************************/
649 int set_message_bcc(char *buf,int num_bytes)
651 int num_words = CVAL(buf,smb_wct);
652 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
653 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
654 return (smb_size + num_words*2 + num_bytes);
657 /*******************************************************************
658 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
659 Return the bytes added
660 ********************************************************************/
662 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
664 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
665 uint8 *tmp;
667 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
668 DEBUG(0, ("talloc failed\n"));
669 return -1;
671 *outbuf = tmp;
673 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
674 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
675 return blob.length;
678 /*******************************************************************
679 Reduce a file name, removing .. elements.
680 ********************************************************************/
682 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
684 char *p = NULL;
685 char *str = NULL;
687 DEBUG(3,("dos_clean_name [%s]\n",s));
689 /* remove any double slashes */
690 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
691 if (!str) {
692 return NULL;
695 /* Remove leading .\\ characters */
696 if(strncmp(str, ".\\", 2) == 0) {
697 trim_string(str, ".\\", NULL);
698 if(*str == 0) {
699 str = talloc_strdup(ctx, ".\\");
700 if (!str) {
701 return NULL;
706 while ((p = strstr_m(str,"\\..\\")) != NULL) {
707 char *s1;
709 *p = 0;
710 s1 = p+3;
712 if ((p=strrchr_m(str,'\\')) != NULL) {
713 *p = 0;
714 } else {
715 *str = 0;
717 str = talloc_asprintf(ctx,
718 "%s%s",
719 str,
720 s1);
721 if (!str) {
722 return NULL;
726 trim_string(str,NULL,"\\..");
727 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
730 /*******************************************************************
731 Reduce a file name, removing .. elements.
732 ********************************************************************/
734 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
736 char *p = NULL;
737 char *str = NULL;
739 DEBUG(3,("unix_clean_name [%s]\n",s));
741 /* remove any double slashes */
742 str = talloc_all_string_sub(ctx, s, "//","/");
743 if (!str) {
744 return NULL;
747 /* Remove leading ./ characters */
748 if(strncmp(str, "./", 2) == 0) {
749 trim_string(str, "./", NULL);
750 if(*str == 0) {
751 str = talloc_strdup(ctx, "./");
752 if (!str) {
753 return NULL;
758 while ((p = strstr_m(str,"/../")) != NULL) {
759 char *s1;
761 *p = 0;
762 s1 = p+3;
764 if ((p=strrchr_m(str,'/')) != NULL) {
765 *p = 0;
766 } else {
767 *str = 0;
769 str = talloc_asprintf(ctx,
770 "%s%s",
771 str,
772 s1);
773 if (!str) {
774 return NULL;
778 trim_string(str,NULL,"/..");
779 return talloc_all_string_sub(ctx, str, "/./", "/");
782 char *clean_name(TALLOC_CTX *ctx, const char *s)
784 char *str = dos_clean_name(ctx, s);
785 if (!str) {
786 return NULL;
788 return unix_clean_name(ctx, str);
791 /*******************************************************************
792 Write data into an fd at a given offset. Ignore seek errors.
793 ********************************************************************/
795 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
797 size_t total=0;
798 ssize_t ret;
800 if (pos == (SMB_OFF_T)-1) {
801 return write_data(fd, buffer, N);
803 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
804 while (total < N) {
805 ret = sys_pwrite(fd,buffer + total,N - total, pos);
806 if (ret == -1 && errno == ESPIPE) {
807 return write_data(fd, buffer + total,N - total);
809 if (ret == -1) {
810 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
811 return -1;
813 if (ret == 0) {
814 return total;
816 total += ret;
817 pos += ret;
819 return (ssize_t)total;
820 #else
821 /* Use lseek and write_data. */
822 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
823 if (errno != ESPIPE) {
824 return -1;
827 return write_data(fd, buffer, N);
828 #endif
832 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
833 struct event_context *ev_ctx,
834 struct server_id id,
835 bool parent_longlived)
837 NTSTATUS status = NT_STATUS_OK;
839 /* Reset the state of the random
840 * number generation system, so
841 * children do not get the same random
842 * numbers as each other */
843 set_need_random_reseed();
845 /* tdb needs special fork handling */
846 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
847 DEBUG(0,("tdb_reopen_all failed.\n"));
848 status = NT_STATUS_OPEN_FAILED;
849 goto done;
852 if (ev_ctx && tevent_re_initialise(ev_ctx) != 0) {
853 smb_panic(__location__ ": Failed to re-initialise event context");
856 if (msg_ctx) {
858 * For clustering, we need to re-init our ctdbd connection after the
859 * fork
861 status = messaging_reinit(msg_ctx, id);
862 if (!NT_STATUS_IS_OK(status)) {
863 DEBUG(0,("messaging_reinit() failed: %s\n",
864 nt_errstr(status)));
867 done:
868 return status;
871 #if defined(PARANOID_MALLOC_CHECKER)
873 /****************************************************************************
874 Internal malloc wrapper. Externally visible.
875 ****************************************************************************/
877 void *malloc_(size_t size)
879 if (size == 0) {
880 return NULL;
882 #undef malloc
883 return malloc(size);
884 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
887 /****************************************************************************
888 Internal calloc wrapper. Not externally visible.
889 ****************************************************************************/
891 static void *calloc_(size_t count, size_t size)
893 if (size == 0 || count == 0) {
894 return NULL;
896 #undef calloc
897 return calloc(count, size);
898 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
901 /****************************************************************************
902 Internal realloc wrapper. Not externally visible.
903 ****************************************************************************/
905 static void *realloc_(void *ptr, size_t size)
907 #undef realloc
908 return realloc(ptr, size);
909 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
912 #endif /* PARANOID_MALLOC_CHECKER */
914 /****************************************************************************
915 Type-safe memalign
916 ****************************************************************************/
918 void *memalign_array(size_t el_size, size_t align, unsigned int count)
920 if (count >= MAX_ALLOC_SIZE/el_size) {
921 return NULL;
924 return sys_memalign(align, el_size*count);
927 /****************************************************************************
928 Type-safe calloc.
929 ****************************************************************************/
931 void *calloc_array(size_t size, size_t nmemb)
933 if (nmemb >= MAX_ALLOC_SIZE/size) {
934 return NULL;
936 if (size == 0 || nmemb == 0) {
937 return NULL;
939 #if defined(PARANOID_MALLOC_CHECKER)
940 return calloc_(nmemb, size);
941 #else
942 return calloc(nmemb, size);
943 #endif
946 /****************************************************************************
947 Expand a pointer to be a particular size.
948 Note that this version of Realloc has an extra parameter that decides
949 whether to free the passed in storage on allocation failure or if the
950 new size is zero.
952 This is designed for use in the typical idiom of :
954 p = SMB_REALLOC(p, size)
955 if (!p) {
956 return error;
959 and not to have to keep track of the old 'p' contents to free later, nor
960 to worry if the size parameter was zero. In the case where NULL is returned
961 we guarentee that p has been freed.
963 If free later semantics are desired, then pass 'free_old_on_error' as False which
964 guarentees that the old contents are not freed on error, even if size == 0. To use
965 this idiom use :
967 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
968 if (!tmp) {
969 SAFE_FREE(p);
970 return error;
971 } else {
972 p = tmp;
975 Changes were instigated by Coverity error checking. JRA.
976 ****************************************************************************/
978 void *Realloc(void *p, size_t size, bool free_old_on_error)
980 void *ret=NULL;
982 if (size == 0) {
983 if (free_old_on_error) {
984 SAFE_FREE(p);
986 DEBUG(2,("Realloc asked for 0 bytes\n"));
987 return NULL;
990 #if defined(PARANOID_MALLOC_CHECKER)
991 if (!p) {
992 ret = (void *)malloc_(size);
993 } else {
994 ret = (void *)realloc_(p,size);
996 #else
997 if (!p) {
998 ret = (void *)malloc(size);
999 } else {
1000 ret = (void *)realloc(p,size);
1002 #endif
1004 if (!ret) {
1005 if (free_old_on_error && p) {
1006 SAFE_FREE(p);
1008 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1011 return(ret);
1014 /****************************************************************************
1015 (Hopefully) efficient array append.
1016 ****************************************************************************/
1018 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1019 void *element, void *_array, uint32 *num_elements,
1020 ssize_t *array_size)
1022 void **array = (void **)_array;
1024 if (*array_size < 0) {
1025 return;
1028 if (*array == NULL) {
1029 if (*array_size == 0) {
1030 *array_size = 128;
1033 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1034 goto error;
1037 *array = TALLOC(mem_ctx, element_size * (*array_size));
1038 if (*array == NULL) {
1039 goto error;
1043 if (*num_elements == *array_size) {
1044 *array_size *= 2;
1046 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1047 goto error;
1050 *array = TALLOC_REALLOC(mem_ctx, *array,
1051 element_size * (*array_size));
1053 if (*array == NULL) {
1054 goto error;
1058 memcpy((char *)(*array) + element_size*(*num_elements),
1059 element, element_size);
1060 *num_elements += 1;
1062 return;
1064 error:
1065 *num_elements = 0;
1066 *array_size = -1;
1069 /****************************************************************************
1070 Get my own domain name, or "" if we have none.
1071 ****************************************************************************/
1073 char *get_mydnsdomname(TALLOC_CTX *ctx)
1075 const char *domname;
1076 char *p;
1078 domname = get_mydnsfullname();
1079 if (!domname) {
1080 return NULL;
1083 p = strchr_m(domname, '.');
1084 if (p) {
1085 p++;
1086 return talloc_strdup(ctx, p);
1087 } else {
1088 return talloc_strdup(ctx, "");
1092 /****************************************************************************
1093 Interpret a protocol description string, with a default.
1094 ****************************************************************************/
1096 int interpret_protocol(const char *str,int def)
1098 if (strequal(str,"NT1"))
1099 return(PROTOCOL_NT1);
1100 if (strequal(str,"LANMAN2"))
1101 return(PROTOCOL_LANMAN2);
1102 if (strequal(str,"LANMAN1"))
1103 return(PROTOCOL_LANMAN1);
1104 if (strequal(str,"CORE"))
1105 return(PROTOCOL_CORE);
1106 if (strequal(str,"COREPLUS"))
1107 return(PROTOCOL_COREPLUS);
1108 if (strequal(str,"CORE+"))
1109 return(PROTOCOL_COREPLUS);
1111 DEBUG(0,("Unrecognised protocol level %s\n",str));
1113 return(def);
1117 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1118 /******************************************************************
1119 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1120 Based on a fix from <Thomas.Hepper@icem.de>.
1121 Returns a malloc'ed string.
1122 *******************************************************************/
1124 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1126 if (*str == '-') {
1127 const char *p = str;
1128 while(*p && !isspace(*p))
1129 p++;
1130 while(*p && isspace(*p))
1131 p++;
1132 if(*p) {
1133 return talloc_strdup(ctx, p);
1136 return NULL;
1139 /*******************************************************************
1140 Patch from jkf@soton.ac.uk
1141 Split Luke's automount_server into YP lookup and string splitter
1142 so can easily implement automount_path().
1143 Returns a malloc'ed string.
1144 *******************************************************************/
1146 #ifdef WITH_NISPLUS_HOME
1147 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1149 char *value = NULL;
1151 char *nis_map = (char *)lp_nis_home_map_name();
1153 char buffer[NIS_MAXATTRVAL + 1];
1154 nis_result *result;
1155 nis_object *object;
1156 entry_obj *entry;
1158 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1159 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1161 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1162 if (result->status != NIS_SUCCESS) {
1163 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1164 } else {
1165 object = result->objects.objects_val;
1166 if (object->zo_data.zo_type == ENTRY_OBJ) {
1167 entry = &object->zo_data.objdata_u.en_data;
1168 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1169 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1171 value = talloc_strdup(ctx,
1172 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1173 if (!value) {
1174 nis_freeresult(result);
1175 return NULL;
1177 value = talloc_string_sub(ctx,
1178 value,
1179 "&",
1180 user_name);
1184 nis_freeresult(result);
1186 if (value) {
1187 value = strip_mount_options(ctx, value);
1188 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1189 user_name, value));
1191 return value;
1193 #else /* WITH_NISPLUS_HOME */
1195 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1197 char *value = NULL;
1199 int nis_error; /* returned by yp all functions */
1200 char *nis_result; /* yp_match inits this */
1201 int nis_result_len; /* and set this */
1202 char *nis_domain; /* yp_get_default_domain inits this */
1203 char *nis_map = (char *)lp_nis_home_map_name();
1205 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1206 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1207 return NULL;
1210 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1212 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1213 strlen(user_name), &nis_result,
1214 &nis_result_len)) == 0) {
1215 if (nis_result_len > 0 && nis_result[nis_result_len] == '\n') {
1216 nis_result[nis_result_len] = '\0';
1218 value = talloc_strdup(ctx, nis_result);
1219 if (!value) {
1220 return NULL;
1222 value = strip_mount_options(ctx, value);
1223 } else if(nis_error == YPERR_KEY) {
1224 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1225 user_name, nis_map));
1226 DEBUG(3, ("using defaults for server and home directory\n"));
1227 } else {
1228 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1229 yperr_string(nis_error), user_name, nis_map));
1232 if (value) {
1233 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1235 return value;
1237 #endif /* WITH_NISPLUS_HOME */
1238 #endif
1240 /****************************************************************************
1241 Check if a process exists. Does this work on all unixes?
1242 ****************************************************************************/
1244 bool process_exists(const struct server_id pid)
1246 if (procid_is_me(&pid)) {
1247 return True;
1250 if (procid_is_local(&pid)) {
1251 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1254 #ifdef CLUSTER_SUPPORT
1255 return ctdbd_process_exists(messaging_ctdbd_connection(),
1256 pid.vnn, pid.pid);
1257 #else
1258 return False;
1259 #endif
1262 /*******************************************************************
1263 Convert a uid into a user name.
1264 ********************************************************************/
1266 const char *uidtoname(uid_t uid)
1268 TALLOC_CTX *ctx = talloc_tos();
1269 char *name = NULL;
1270 struct passwd *pass = NULL;
1272 pass = getpwuid_alloc(ctx,uid);
1273 if (pass) {
1274 name = talloc_strdup(ctx,pass->pw_name);
1275 TALLOC_FREE(pass);
1276 } else {
1277 name = talloc_asprintf(ctx,
1278 "%ld",
1279 (long int)uid);
1281 return name;
1284 /*******************************************************************
1285 Convert a gid into a group name.
1286 ********************************************************************/
1288 char *gidtoname(gid_t gid)
1290 struct group *grp;
1292 grp = getgrgid(gid);
1293 if (grp) {
1294 return talloc_strdup(talloc_tos(), grp->gr_name);
1296 else {
1297 return talloc_asprintf(talloc_tos(),
1298 "%d",
1299 (int)gid);
1303 /*******************************************************************
1304 Convert a user name into a uid.
1305 ********************************************************************/
1307 uid_t nametouid(const char *name)
1309 struct passwd *pass;
1310 char *p;
1311 uid_t u;
1313 pass = Get_Pwnam_alloc(talloc_tos(), name);
1314 if (pass) {
1315 u = pass->pw_uid;
1316 TALLOC_FREE(pass);
1317 return u;
1320 u = (uid_t)strtol(name, &p, 0);
1321 if ((p != name) && (*p == '\0'))
1322 return u;
1324 return (uid_t)-1;
1327 /*******************************************************************
1328 Convert a name to a gid_t if possible. Return -1 if not a group.
1329 ********************************************************************/
1331 gid_t nametogid(const char *name)
1333 struct group *grp;
1334 char *p;
1335 gid_t g;
1337 g = (gid_t)strtol(name, &p, 0);
1338 if ((p != name) && (*p == '\0'))
1339 return g;
1341 grp = sys_getgrnam(name);
1342 if (grp)
1343 return(grp->gr_gid);
1344 return (gid_t)-1;
1347 /*******************************************************************
1348 Something really nasty happened - panic !
1349 ********************************************************************/
1351 void smb_panic(const char *const why)
1353 char *cmd;
1354 int result;
1356 #ifdef DEVELOPER
1359 if (global_clobber_region_function) {
1360 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1361 global_clobber_region_function,
1362 global_clobber_region_line));
1365 #endif
1367 DEBUG(0,("PANIC (pid %llu): %s\n",
1368 (unsigned long long)sys_getpid(), why));
1369 log_stack_trace();
1371 cmd = lp_panic_action();
1372 if (cmd && *cmd) {
1373 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1374 result = system(cmd);
1376 if (result == -1)
1377 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1378 strerror(errno)));
1379 else
1380 DEBUG(0, ("smb_panic(): action returned status %d\n",
1381 WEXITSTATUS(result)));
1384 dump_core();
1387 /*******************************************************************
1388 Print a backtrace of the stack to the debug log. This function
1389 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1390 exit shortly after calling it.
1391 ********************************************************************/
1393 #ifdef HAVE_LIBUNWIND_H
1394 #include <libunwind.h>
1395 #endif
1397 #ifdef HAVE_EXECINFO_H
1398 #include <execinfo.h>
1399 #endif
1401 #ifdef HAVE_LIBEXC_H
1402 #include <libexc.h>
1403 #endif
1405 void log_stack_trace(void)
1407 #ifdef HAVE_LIBUNWIND
1408 /* Try to use libunwind before any other technique since on ia64
1409 * libunwind correctly walks the stack in more circumstances than
1410 * backtrace.
1412 unw_cursor_t cursor;
1413 unw_context_t uc;
1414 unsigned i = 0;
1416 char procname[256];
1417 unw_word_t ip, sp, off;
1419 procname[sizeof(procname) - 1] = '\0';
1421 if (unw_getcontext(&uc) != 0) {
1422 goto libunwind_failed;
1425 if (unw_init_local(&cursor, &uc) != 0) {
1426 goto libunwind_failed;
1429 DEBUG(0, ("BACKTRACE:\n"));
1431 do {
1432 ip = sp = 0;
1433 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1434 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1436 switch (unw_get_proc_name(&cursor,
1437 procname, sizeof(procname) - 1, &off) ) {
1438 case 0:
1439 /* Name found. */
1440 case -UNW_ENOMEM:
1441 /* Name truncated. */
1442 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1443 i, procname, (long long)off,
1444 (long long)ip, (long long) sp));
1445 break;
1446 default:
1447 /* case -UNW_ENOINFO: */
1448 /* case -UNW_EUNSPEC: */
1449 /* No symbol name found. */
1450 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1451 i, "<unknown symbol>",
1452 (long long)ip, (long long) sp));
1454 ++i;
1455 } while (unw_step(&cursor) > 0);
1457 return;
1459 libunwind_failed:
1460 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1462 #elif HAVE_BACKTRACE_SYMBOLS
1463 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1464 size_t backtrace_size;
1465 char **backtrace_strings;
1467 /* get the backtrace (stack frames) */
1468 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1469 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1471 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1472 (unsigned long)backtrace_size));
1474 if (backtrace_strings) {
1475 int i;
1477 for (i = 0; i < backtrace_size; i++)
1478 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1480 /* Leak the backtrace_strings, rather than risk what free() might do */
1483 #elif HAVE_LIBEXC
1485 /* The IRIX libexc library provides an API for unwinding the stack. See
1486 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1487 * since we are about to abort anyway, it hardly matters.
1490 #define NAMESIZE 32 /* Arbitrary */
1492 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1493 char * names[BACKTRACE_STACK_SIZE];
1494 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1496 int i;
1497 int levels;
1499 ZERO_ARRAY(addrs);
1500 ZERO_ARRAY(names);
1501 ZERO_ARRAY(namebuf);
1503 /* We need to be root so we can open our /proc entry to walk
1504 * our stack. It also helps when we want to dump core.
1506 become_root();
1508 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1509 names[i] = namebuf + (i * NAMESIZE);
1512 levels = trace_back_stack(0, addrs, names,
1513 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1515 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1516 for (i = 0; i < levels; i++) {
1517 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1519 #undef NAMESIZE
1521 #else
1522 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1523 #endif
1526 /*******************************************************************
1527 A readdir wrapper which just returns the file name.
1528 ********************************************************************/
1530 const char *readdirname(SMB_STRUCT_DIR *p)
1532 SMB_STRUCT_DIRENT *ptr;
1533 char *dname;
1535 if (!p)
1536 return(NULL);
1538 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1539 if (!ptr)
1540 return(NULL);
1542 dname = ptr->d_name;
1544 #ifdef NEXT2
1545 if (telldir(p) < 0)
1546 return(NULL);
1547 #endif
1549 #ifdef HAVE_BROKEN_READDIR_NAME
1550 /* using /usr/ucb/cc is BAD */
1551 dname = dname - 2;
1552 #endif
1554 return talloc_strdup(talloc_tos(), dname);
1557 /*******************************************************************
1558 Utility function used to decide if the last component
1559 of a path matches a (possibly wildcarded) entry in a namelist.
1560 ********************************************************************/
1562 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1564 const char *last_component;
1566 /* if we have no list it's obviously not in the path */
1567 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1568 return False;
1571 DEBUG(8, ("is_in_path: %s\n", name));
1573 /* Get the last component of the unix name. */
1574 last_component = strrchr_m(name, '/');
1575 if (!last_component) {
1576 last_component = name;
1577 } else {
1578 last_component++; /* Go past '/' */
1581 for(; namelist->name != NULL; namelist++) {
1582 if(namelist->is_wild) {
1583 if (mask_match(last_component, namelist->name, case_sensitive)) {
1584 DEBUG(8,("is_in_path: mask match succeeded\n"));
1585 return True;
1587 } else {
1588 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1589 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1590 DEBUG(8,("is_in_path: match succeeded\n"));
1591 return True;
1595 DEBUG(8,("is_in_path: match not found\n"));
1596 return False;
1599 /*******************************************************************
1600 Strip a '/' separated list into an array of
1601 name_compare_enties structures suitable for
1602 passing to is_in_path(). We do this for
1603 speed so we can pre-parse all the names in the list
1604 and don't do it for each call to is_in_path().
1605 namelist is modified here and is assumed to be
1606 a copy owned by the caller.
1607 We also check if the entry contains a wildcard to
1608 remove a potentially expensive call to mask_match
1609 if possible.
1610 ********************************************************************/
1612 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
1614 char *name_end;
1615 char *nameptr = (char *)namelist;
1616 int num_entries = 0;
1617 int i;
1619 (*ppname_array) = NULL;
1621 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1622 return;
1624 /* We need to make two passes over the string. The
1625 first to count the number of elements, the second
1626 to split it.
1629 while(*nameptr) {
1630 if ( *nameptr == '/' ) {
1631 /* cope with multiple (useless) /s) */
1632 nameptr++;
1633 continue;
1635 /* anything left? */
1636 if ( *nameptr == '\0' )
1637 break;
1639 /* find the next '/' or consume remaining */
1640 name_end = strchr_m(nameptr, '/');
1641 if (name_end == NULL)
1642 name_end = (char *)nameptr + strlen(nameptr);
1644 /* next segment please */
1645 nameptr = name_end + 1;
1646 num_entries++;
1649 if(num_entries == 0)
1650 return;
1652 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1653 DEBUG(0,("set_namearray: malloc fail\n"));
1654 return;
1657 /* Now copy out the names */
1658 nameptr = (char *)namelist;
1659 i = 0;
1660 while(*nameptr) {
1661 if ( *nameptr == '/' ) {
1662 /* cope with multiple (useless) /s) */
1663 nameptr++;
1664 continue;
1666 /* anything left? */
1667 if ( *nameptr == '\0' )
1668 break;
1670 /* find the next '/' or consume remaining */
1671 name_end = strchr_m(nameptr, '/');
1672 if (name_end)
1673 *name_end = '\0';
1674 else
1675 name_end = nameptr + strlen(nameptr);
1677 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1678 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1679 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1680 return;
1683 /* next segment please */
1684 nameptr = name_end + 1;
1685 i++;
1688 (*ppname_array)[i].name = NULL;
1690 return;
1693 /****************************************************************************
1694 Routine to free a namearray.
1695 ****************************************************************************/
1697 void free_namearray(name_compare_entry *name_array)
1699 int i;
1701 if(name_array == NULL)
1702 return;
1704 for(i=0; name_array[i].name!=NULL; i++)
1705 SAFE_FREE(name_array[i].name);
1706 SAFE_FREE(name_array);
1709 #undef DBGC_CLASS
1710 #define DBGC_CLASS DBGC_LOCKING
1712 /****************************************************************************
1713 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1714 is dealt with in posix.c
1715 Returns True if we have information regarding this lock region (and returns
1716 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1717 ****************************************************************************/
1719 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1721 SMB_STRUCT_FLOCK lock;
1722 int ret;
1724 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1725 fd,(double)*poffset,(double)*pcount,*ptype));
1727 lock.l_type = *ptype;
1728 lock.l_whence = SEEK_SET;
1729 lock.l_start = *poffset;
1730 lock.l_len = *pcount;
1731 lock.l_pid = 0;
1733 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1735 if (ret == -1) {
1736 int sav = errno;
1737 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1738 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1739 errno = sav;
1740 return False;
1743 *ptype = lock.l_type;
1744 *poffset = lock.l_start;
1745 *pcount = lock.l_len;
1746 *ppid = lock.l_pid;
1748 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1749 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1750 return True;
1753 #undef DBGC_CLASS
1754 #define DBGC_CLASS DBGC_ALL
1756 /*******************************************************************
1757 Is the name specified one of my netbios names.
1758 Returns true if it is equal, false otherwise.
1759 ********************************************************************/
1761 bool is_myname(const char *s)
1763 int n;
1764 bool ret = False;
1766 for (n=0; my_netbios_names(n); n++) {
1767 if (strequal(my_netbios_names(n), s)) {
1768 ret=True;
1769 break;
1772 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1773 return(ret);
1776 /*******************************************************************
1777 Is the name specified our workgroup/domain.
1778 Returns true if it is equal, false otherwise.
1779 ********************************************************************/
1781 bool is_myworkgroup(const char *s)
1783 bool ret = False;
1785 if (strequal(s, lp_workgroup())) {
1786 ret=True;
1789 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1790 return(ret);
1793 /*******************************************************************
1794 we distinguish between 2K and XP by the "Native Lan Manager" string
1795 WinXP => "Windows 2002 5.1"
1796 WinXP 64bit => "Windows XP 5.2"
1797 Win2k => "Windows 2000 5.0"
1798 NT4 => "Windows NT 4.0"
1799 Win9x => "Windows 4.0"
1800 Windows 2003 doesn't set the native lan manager string but
1801 they do set the domain to "Windows 2003 5.2" (probably a bug).
1802 ********************************************************************/
1804 void ra_lanman_string( const char *native_lanman )
1806 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1807 set_remote_arch( RA_WINXP );
1808 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1809 set_remote_arch( RA_WINXP64 );
1810 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1811 set_remote_arch( RA_WIN2K3 );
1814 static const char *remote_arch_str;
1816 const char *get_remote_arch_str(void)
1818 if (!remote_arch_str) {
1819 return "UNKNOWN";
1821 return remote_arch_str;
1824 /*******************************************************************
1825 Set the horrid remote_arch string based on an enum.
1826 ********************************************************************/
1828 void set_remote_arch(enum remote_arch_types type)
1830 ra_type = type;
1831 switch( type ) {
1832 case RA_WFWG:
1833 remote_arch_str = "WfWg";
1834 break;
1835 case RA_OS2:
1836 remote_arch_str = "OS2";
1837 break;
1838 case RA_WIN95:
1839 remote_arch_str = "Win95";
1840 break;
1841 case RA_WINNT:
1842 remote_arch_str = "WinNT";
1843 break;
1844 case RA_WIN2K:
1845 remote_arch_str = "Win2K";
1846 break;
1847 case RA_WINXP:
1848 remote_arch_str = "WinXP";
1849 break;
1850 case RA_WINXP64:
1851 remote_arch_str = "WinXP64";
1852 break;
1853 case RA_WIN2K3:
1854 remote_arch_str = "Win2K3";
1855 break;
1856 case RA_VISTA:
1857 remote_arch_str = "Vista";
1858 break;
1859 case RA_SAMBA:
1860 remote_arch_str = "Samba";
1861 break;
1862 case RA_CIFSFS:
1863 remote_arch_str = "CIFSFS";
1864 break;
1865 case RA_OSX:
1866 remote_arch_str = "OSX";
1867 break;
1868 default:
1869 ra_type = RA_UNKNOWN;
1870 remote_arch_str = "UNKNOWN";
1871 break;
1874 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1875 remote_arch_str));
1878 /*******************************************************************
1879 Get the remote_arch type.
1880 ********************************************************************/
1882 enum remote_arch_types get_remote_arch(void)
1884 return ra_type;
1887 const char *tab_depth(int level, int depth)
1889 if( CHECK_DEBUGLVL(level) ) {
1890 dbgtext("%*s", depth*4, "");
1892 return "";
1895 /*****************************************************************************
1896 Provide a checksum on a string
1898 Input: s - the null-terminated character string for which the checksum
1899 will be calculated.
1901 Output: The checksum value calculated for s.
1902 *****************************************************************************/
1904 int str_checksum(const char *s)
1906 TDB_DATA key = string_tdb_data(s);
1907 return tdb_jenkins_hash(&key);
1910 /*****************************************************************
1911 Zero a memory area then free it. Used to catch bugs faster.
1912 *****************************************************************/
1914 void zero_free(void *p, size_t size)
1916 memset(p, 0, size);
1917 SAFE_FREE(p);
1920 /*****************************************************************
1921 Set our open file limit to a requested max and return the limit.
1922 *****************************************************************/
1924 int set_maxfiles(int requested_max)
1926 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
1927 struct rlimit rlp;
1928 int saved_current_limit;
1930 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1931 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
1932 strerror(errno) ));
1933 /* just guess... */
1934 return requested_max;
1938 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
1939 * account for the extra fd we need
1940 * as well as the log files and standard
1941 * handles etc. Save the limit we want to set in case
1942 * we are running on an OS that doesn't support this limit (AIX)
1943 * which always returns RLIM_INFINITY for rlp.rlim_max.
1946 /* Try raising the hard (max) limit to the requested amount. */
1948 #if defined(RLIM_INFINITY)
1949 if (rlp.rlim_max != RLIM_INFINITY) {
1950 int orig_max = rlp.rlim_max;
1952 if ( rlp.rlim_max < requested_max )
1953 rlp.rlim_max = requested_max;
1955 /* This failing is not an error - many systems (Linux) don't
1956 support our default request of 10,000 open files. JRA. */
1958 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1959 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
1960 (int)rlp.rlim_max, strerror(errno) ));
1962 /* Set failed - restore original value from get. */
1963 rlp.rlim_max = orig_max;
1966 #endif
1968 /* Now try setting the soft (current) limit. */
1970 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
1972 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
1973 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
1974 (int)rlp.rlim_cur, strerror(errno) ));
1975 /* just guess... */
1976 return saved_current_limit;
1979 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
1980 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
1981 strerror(errno) ));
1982 /* just guess... */
1983 return saved_current_limit;
1986 #if defined(RLIM_INFINITY)
1987 if(rlp.rlim_cur == RLIM_INFINITY)
1988 return saved_current_limit;
1989 #endif
1991 if((int)rlp.rlim_cur > saved_current_limit)
1992 return saved_current_limit;
1994 return rlp.rlim_cur;
1995 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
1997 * No way to know - just guess...
1999 return requested_max;
2000 #endif
2003 /*****************************************************************
2004 malloc that aborts with smb_panic on fail or zero size.
2005 *****************************************************************/
2007 void *smb_xmalloc_array(size_t size, unsigned int count)
2009 void *p;
2010 if (size == 0) {
2011 smb_panic("smb_xmalloc_array: called with zero size");
2013 if (count >= MAX_ALLOC_SIZE/size) {
2014 smb_panic("smb_xmalloc_array: alloc size too large");
2016 if ((p = SMB_MALLOC(size*count)) == NULL) {
2017 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2018 (unsigned long)size, (unsigned long)count));
2019 smb_panic("smb_xmalloc_array: malloc failed");
2021 return p;
2025 vasprintf that aborts on malloc fail
2028 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2030 int n;
2031 va_list ap2;
2033 va_copy(ap2, ap);
2035 n = vasprintf(ptr, format, ap2);
2036 va_end(ap2);
2037 if (n == -1 || ! *ptr) {
2038 smb_panic("smb_xvasprintf: out of memory");
2040 return n;
2043 /*****************************************************************
2044 Get local hostname and cache result.
2045 *****************************************************************/
2047 char *myhostname(void)
2049 static char *ret;
2050 if (ret == NULL) {
2051 ret = get_myname(NULL);
2053 return ret;
2057 * @brief Returns an absolute path to a file concatenating the provided
2058 * @a rootpath and @a basename
2060 * @param name Filename, relative to @a rootpath
2062 * @retval Pointer to a string containing the full path.
2065 static char *xx_path(const char *name, const char *rootpath)
2067 char *fname = NULL;
2069 fname = talloc_strdup(talloc_tos(), rootpath);
2070 if (!fname) {
2071 return NULL;
2073 trim_string(fname,"","/");
2075 if (!directory_exist(fname)) {
2076 if (!mkdir(fname,0755))
2077 DEBUG(1, ("Unable to create directory %s for file %s. "
2078 "Error was %s\n", fname, name, strerror(errno)));
2081 return talloc_asprintf(talloc_tos(),
2082 "%s/%s",
2083 fname,
2084 name);
2088 * @brief Returns an absolute path to a file in the Samba lock directory.
2090 * @param name File to find, relative to LOCKDIR.
2092 * @retval Pointer to a talloc'ed string containing the full path.
2095 char *lock_path(const char *name)
2097 return xx_path(name, lp_lockdir());
2101 * @brief Returns an absolute path to a file in the Samba pid directory.
2103 * @param name File to find, relative to PIDDIR.
2105 * @retval Pointer to a talloc'ed string containing the full path.
2108 char *pid_path(const char *name)
2110 return xx_path(name, lp_piddir());
2114 * @brief Returns an absolute path to a file in the Samba lib directory.
2116 * @param name File to find, relative to LIBDIR.
2118 * @retval Pointer to a string containing the full path.
2121 char *lib_path(const char *name)
2123 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2127 * @brief Returns an absolute path to a file in the Samba modules directory.
2129 * @param name File to find, relative to MODULESDIR.
2131 * @retval Pointer to a string containing the full path.
2134 char *modules_path(const char *name)
2136 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
2140 * @brief Returns an absolute path to a file in the Samba data directory.
2142 * @param name File to find, relative to CODEPAGEDIR.
2144 * @retval Pointer to a talloc'ed string containing the full path.
2147 char *data_path(const char *name)
2149 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2153 * @brief Returns an absolute path to a file in the Samba state directory.
2155 * @param name File to find, relative to STATEDIR.
2157 * @retval Pointer to a talloc'ed string containing the full path.
2160 char *state_path(const char *name)
2162 return xx_path(name, lp_statedir());
2166 * @brief Returns an absolute path to a file in the Samba cache directory.
2168 * @param name File to find, relative to CACHEDIR.
2170 * @retval Pointer to a talloc'ed string containing the full path.
2173 char *cache_path(const char *name)
2175 return xx_path(name, lp_cachedir());
2179 * @brief Returns the platform specific shared library extension.
2181 * @retval Pointer to a const char * containing the extension.
2184 const char *shlib_ext(void)
2186 return get_dyn_SHLIBEXT();
2189 /*******************************************************************
2190 Given a filename - get its directory name
2191 ********************************************************************/
2193 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
2194 const char **name)
2196 char *p;
2197 ptrdiff_t len;
2199 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2201 if (p == NULL) {
2202 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2203 return False;
2205 if (name) {
2206 *name = dir;
2208 return True;
2211 len = p-dir;
2213 if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
2214 return False;
2216 (*parent)[len] = '\0';
2218 if (name) {
2219 *name = p+1;
2221 return True;
2224 /*******************************************************************
2225 Determine if a pattern contains any Microsoft wildcard characters.
2226 *******************************************************************/
2228 bool ms_has_wild(const char *s)
2230 char c;
2232 if (lp_posix_pathnames()) {
2233 /* With posix pathnames no characters are wild. */
2234 return False;
2237 while ((c = *s++)) {
2238 switch (c) {
2239 case '*':
2240 case '?':
2241 case '<':
2242 case '>':
2243 case '"':
2244 return True;
2247 return False;
2250 bool ms_has_wild_w(const smb_ucs2_t *s)
2252 smb_ucs2_t c;
2253 if (!s) return False;
2254 while ((c = *s++)) {
2255 switch (c) {
2256 case UCS2_CHAR('*'):
2257 case UCS2_CHAR('?'):
2258 case UCS2_CHAR('<'):
2259 case UCS2_CHAR('>'):
2260 case UCS2_CHAR('"'):
2261 return True;
2264 return False;
2267 /*******************************************************************
2268 A wrapper that handles case sensitivity and the special handling
2269 of the ".." name.
2270 *******************************************************************/
2272 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2274 if (ISDOTDOT(string))
2275 string = ".";
2276 if (ISDOT(pattern))
2277 return False;
2279 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2282 /*******************************************************************
2283 A wrapper that handles case sensitivity and the special handling
2284 of the ".." name. Varient that is only called by old search code which requires
2285 pattern translation.
2286 *******************************************************************/
2288 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2290 if (ISDOTDOT(string))
2291 string = ".";
2292 if (ISDOT(pattern))
2293 return False;
2295 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2298 /*******************************************************************
2299 A wrapper that handles a list of patters and calls mask_match()
2300 on each. Returns True if any of the patterns match.
2301 *******************************************************************/
2303 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2305 while (listLen-- > 0) {
2306 if (mask_match(string, *list++, is_case_sensitive))
2307 return True;
2309 return False;
2312 /*********************************************************
2313 Recursive routine that is called by unix_wild_match.
2314 *********************************************************/
2316 static bool unix_do_match(const char *regexp, const char *str)
2318 const char *p;
2320 for( p = regexp; *p && *str; ) {
2322 switch(*p) {
2323 case '?':
2324 str++;
2325 p++;
2326 break;
2328 case '*':
2331 * Look for a character matching
2332 * the one after the '*'.
2334 p++;
2335 if(!*p)
2336 return true; /* Automatic match */
2337 while(*str) {
2339 while(*str && (*p != *str))
2340 str++;
2343 * Patch from weidel@multichart.de. In the case of the regexp
2344 * '*XX*' we want to ensure there are at least 2 'X' characters
2345 * in the string after the '*' for a match to be made.
2349 int matchcount=0;
2352 * Eat all the characters that match, but count how many there were.
2355 while(*str && (*p == *str)) {
2356 str++;
2357 matchcount++;
2361 * Now check that if the regexp had n identical characters that
2362 * matchcount had at least that many matches.
2365 while ( *(p+1) && (*(p+1) == *p)) {
2366 p++;
2367 matchcount--;
2370 if ( matchcount <= 0 )
2371 return false;
2374 str--; /* We've eaten the match char after the '*' */
2376 if(unix_do_match(p, str))
2377 return true;
2379 if(!*str)
2380 return false;
2381 else
2382 str++;
2384 return false;
2386 default:
2387 if(*str != *p)
2388 return false;
2389 str++;
2390 p++;
2391 break;
2395 if(!*p && !*str)
2396 return true;
2398 if (!*p && str[0] == '.' && str[1] == 0)
2399 return true;
2401 if (!*str && *p == '?') {
2402 while (*p == '?')
2403 p++;
2404 return(!*p);
2407 if(!*str && (*p == '*' && p[1] == '\0'))
2408 return true;
2410 return false;
2413 /*******************************************************************
2414 Simple case insensitive interface to a UNIX wildcard matcher.
2415 Returns True if match, False if not.
2416 *******************************************************************/
2418 bool unix_wild_match(const char *pattern, const char *string)
2420 TALLOC_CTX *ctx = talloc_stackframe();
2421 char *p2;
2422 char *s2;
2423 char *p;
2424 bool ret = false;
2426 p2 = talloc_strdup(ctx,pattern);
2427 s2 = talloc_strdup(ctx,string);
2428 if (!p2 || !s2) {
2429 TALLOC_FREE(ctx);
2430 return false;
2432 strlower_m(p2);
2433 strlower_m(s2);
2435 /* Remove any *? and ** from the pattern as they are meaningless */
2436 for(p = p2; *p; p++) {
2437 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2438 memmove(&p[1], &p[2], strlen(&p[2])+1);
2442 if (strequal(p2,"*")) {
2443 TALLOC_FREE(ctx);
2444 return true;
2447 ret = unix_do_match(p2, s2);
2448 TALLOC_FREE(ctx);
2449 return ret;
2452 /**********************************************************************
2453 Converts a name to a fully qualified domain name.
2454 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2455 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2456 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2457 ***********************************************************************/
2459 bool name_to_fqdn(fstring fqdn, const char *name)
2461 char *full = NULL;
2462 struct hostent *hp = gethostbyname(name);
2464 if (!hp || !hp->h_name || !*hp->h_name) {
2465 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2466 fstrcpy(fqdn, name);
2467 return false;
2470 /* Find out if the fqdn is returned as an alias
2471 * to cope with /etc/hosts files where the first
2472 * name is not the fqdn but the short name */
2473 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2474 int i;
2475 for (i = 0; hp->h_aliases[i]; i++) {
2476 if (strchr_m(hp->h_aliases[i], '.')) {
2477 full = hp->h_aliases[i];
2478 break;
2482 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2483 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2484 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2485 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2486 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2487 full = hp->h_name;
2489 if (!full) {
2490 full = hp->h_name;
2493 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2494 fstrcpy(fqdn, full);
2495 return true;
2498 /**********************************************************************
2499 Append a DATA_BLOB to a talloc'ed object
2500 ***********************************************************************/
2502 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
2504 size_t old_size = 0;
2505 char *result;
2507 if (blob.length == 0) {
2508 return buf;
2511 if (buf != NULL) {
2512 old_size = talloc_get_size(buf);
2515 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
2516 if (result == NULL) {
2517 return NULL;
2520 memcpy(result + old_size, blob.data, blob.length);
2521 return result;
2524 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2526 switch (share_access & ~FILE_SHARE_DELETE) {
2527 case FILE_SHARE_NONE:
2528 return DENY_ALL;
2529 case FILE_SHARE_READ:
2530 return DENY_WRITE;
2531 case FILE_SHARE_WRITE:
2532 return DENY_READ;
2533 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2534 return DENY_NONE;
2536 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2537 return DENY_DOS;
2538 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2539 return DENY_FCB;
2542 return (uint32)-1;
2545 pid_t procid_to_pid(const struct server_id *proc)
2547 return proc->pid;
2550 static uint32 my_vnn = NONCLUSTER_VNN;
2552 void set_my_vnn(uint32 vnn)
2554 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2555 my_vnn = vnn;
2558 uint32 get_my_vnn(void)
2560 return my_vnn;
2563 static uint64_t my_unique_id = 0;
2565 void set_my_unique_id(uint64_t unique_id)
2567 my_unique_id = unique_id;
2570 struct server_id pid_to_procid(pid_t pid)
2572 struct server_id result;
2573 result.pid = pid;
2574 result.unique_id = my_unique_id;
2575 result.vnn = my_vnn;
2576 return result;
2579 struct server_id procid_self(void)
2581 return pid_to_procid(sys_getpid());
2584 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2586 if (p1->pid != p2->pid)
2587 return False;
2588 if (p1->vnn != p2->vnn)
2589 return False;
2590 return True;
2593 bool cluster_id_equal(const struct server_id *id1,
2594 const struct server_id *id2)
2596 return procid_equal(id1, id2);
2599 bool procid_is_me(const struct server_id *pid)
2601 if (pid->pid != sys_getpid())
2602 return False;
2603 if (pid->vnn != my_vnn)
2604 return False;
2605 return True;
2608 struct server_id interpret_pid(const char *pid_string)
2610 struct server_id result;
2611 int pid;
2612 unsigned int vnn;
2613 if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
2614 result.vnn = vnn;
2615 result.pid = pid;
2617 else if (sscanf(pid_string, "%d", &pid) == 1) {
2618 result.vnn = get_my_vnn();
2619 result.pid = pid;
2621 else {
2622 result.vnn = NONCLUSTER_VNN;
2623 result.pid = -1;
2625 /* Assigning to result.pid may have overflowed
2626 Map negative pid to -1: i.e. error */
2627 if (result.pid < 0) {
2628 result.pid = -1;
2630 result.unique_id = 0;
2631 return result;
2634 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2636 if (pid->vnn == NONCLUSTER_VNN) {
2637 return talloc_asprintf(mem_ctx,
2638 "%d",
2639 (int)pid->pid);
2641 else {
2642 return talloc_asprintf(mem_ctx,
2643 "%u:%d",
2644 (unsigned)pid->vnn,
2645 (int)pid->pid);
2649 char *procid_str_static(const struct server_id *pid)
2651 return procid_str(talloc_tos(), pid);
2654 bool procid_valid(const struct server_id *pid)
2656 return (pid->pid != -1);
2659 bool procid_is_local(const struct server_id *pid)
2661 return pid->vnn == my_vnn;
2664 /****************************************************************
2665 Check if offset/length fit into bufsize. Should probably be
2666 merged with is_offset_safe, but this would require a rewrite
2667 of lanman.c. Later :-)
2668 ****************************************************************/
2670 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2672 if ((offset + length < offset) || (offset + length < length)) {
2673 /* wrap */
2674 return true;
2676 if ((offset > bufsize) || (offset + length > bufsize)) {
2677 /* overflow */
2678 return true;
2680 return false;
2683 /****************************************************************
2684 Check if an offset into a buffer is safe.
2685 If this returns True it's safe to indirect into the byte at
2686 pointer ptr+off.
2687 ****************************************************************/
2689 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2691 const char *end_base = buf_base + buf_len;
2692 char *end_ptr = ptr + off;
2694 if (!buf_base || !ptr) {
2695 return False;
2698 if (end_base < buf_base || end_ptr < ptr) {
2699 return False; /* wrap. */
2702 if (end_ptr < end_base) {
2703 return True;
2705 return False;
2708 /****************************************************************
2709 Return a safe pointer into a buffer, or NULL.
2710 ****************************************************************/
2712 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2714 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2715 ptr + off : NULL;
2718 /****************************************************************
2719 Return a safe pointer into a string within a buffer, or NULL.
2720 ****************************************************************/
2722 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2724 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2725 return NULL;
2727 /* Check if a valid string exists at this offset. */
2728 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2729 return NULL;
2731 return ptr + off;
2734 /****************************************************************
2735 Return an SVAL at a pointer, or failval if beyond the end.
2736 ****************************************************************/
2738 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2741 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2742 * NOT ptr[2].
2744 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2745 return failval;
2747 return SVAL(ptr,off);
2750 /****************************************************************
2751 Return an IVAL at a pointer, or failval if beyond the end.
2752 ****************************************************************/
2754 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2757 * Note we use off+3 here, not off+4 as IVAL accesses
2758 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2760 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2761 return failval;
2763 return IVAL(ptr,off);
2766 /****************************************************************
2767 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2768 call (they take care of winbind separator and other winbind specific settings).
2769 ****************************************************************/
2771 void split_domain_user(TALLOC_CTX *mem_ctx,
2772 const char *full_name,
2773 char **domain,
2774 char **user)
2776 const char *p = NULL;
2778 p = strchr_m(full_name, '\\');
2780 if (p != NULL) {
2781 *domain = talloc_strndup(mem_ctx, full_name,
2782 PTR_DIFF(p, full_name));
2783 *user = talloc_strdup(mem_ctx, p+1);
2784 } else {
2785 *domain = talloc_strdup(mem_ctx, "");
2786 *user = talloc_strdup(mem_ctx, full_name);
2790 #if 0
2792 Disable these now we have checked all code paths and ensured
2793 NULL returns on zero request. JRA.
2795 /****************************************************************
2796 talloc wrapper functions that guarentee a null pointer return
2797 if size == 0.
2798 ****************************************************************/
2800 #ifndef MAX_TALLOC_SIZE
2801 #define MAX_TALLOC_SIZE 0x10000000
2802 #endif
2805 * talloc and zero memory.
2806 * - returns NULL if size is zero.
2809 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2811 void *p;
2813 if (size == 0) {
2814 return NULL;
2817 p = talloc_named_const(ctx, size, name);
2819 if (p) {
2820 memset(p, '\0', size);
2823 return p;
2827 * memdup with a talloc.
2828 * - returns NULL if size is zero.
2831 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
2833 void *newp;
2835 if (size == 0) {
2836 return NULL;
2839 newp = talloc_named_const(t, size, name);
2840 if (newp) {
2841 memcpy(newp, p, size);
2844 return newp;
2848 * alloc an array, checking for integer overflow in the array size.
2849 * - returns NULL if count or el_size are zero.
2852 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2854 if (count >= MAX_TALLOC_SIZE/el_size) {
2855 return NULL;
2858 if (el_size == 0 || count == 0) {
2859 return NULL;
2862 return talloc_named_const(ctx, el_size * count, name);
2866 * alloc an zero array, checking for integer overflow in the array size
2867 * - returns NULL if count or el_size are zero.
2870 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2872 if (count >= MAX_TALLOC_SIZE/el_size) {
2873 return NULL;
2876 if (el_size == 0 || count == 0) {
2877 return NULL;
2880 return _talloc_zero(ctx, el_size * count, name);
2884 * Talloc wrapper that returns NULL if size == 0.
2886 void *talloc_zeronull(const void *context, size_t size, const char *name)
2888 if (size == 0) {
2889 return NULL;
2891 return talloc_named_const(context, size, name);
2893 #endif
2895 /****************************************************************
2896 strip off leading '\\' from a hostname
2897 ****************************************************************/
2899 const char *strip_hostname(const char *s)
2901 if (!s) {
2902 return NULL;
2905 if (strlen_m(s) < 3) {
2906 return s;
2909 if (s[0] == '\\') s++;
2910 if (s[0] == '\\') s++;
2912 return s;
2915 bool tevent_req_poll_ntstatus(struct tevent_req *req,
2916 struct tevent_context *ev,
2917 NTSTATUS *status)
2919 bool ret = tevent_req_poll(req, ev);
2920 if (!ret) {
2921 *status = map_nt_error_from_unix(errno);
2923 return ret;
2926 bool any_nt_status_not_ok(NTSTATUS err1, NTSTATUS err2, NTSTATUS *result)
2928 if (!NT_STATUS_IS_OK(err1)) {
2929 *result = err1;
2930 return true;
2932 if (!NT_STATUS_IS_OK(err2)) {
2933 *result = err2;
2934 return true;
2936 return false;
2939 int timeval_to_msec(struct timeval t)
2941 return t.tv_sec * 1000 + (t.tv_usec+999) / 1000;