s4: Fix a few warnings.
[Samba/fernandojvsilva.git] / source3 / lib / util.c
blob8525d9c919e9f497befd6a2dcfca89f113f5a170
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"
26 extern char *global_clobber_region_function;
27 extern unsigned int global_clobber_region_line;
29 /* Max allowable allococation - 256mb - 0x10000000 */
30 #define MAX_ALLOC_SIZE (1024*1024*256)
32 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
33 #ifdef WITH_NISPLUS_HOME
34 #ifdef BROKEN_NISPLUS_INCLUDE_FILES
36 * The following lines are needed due to buggy include files
37 * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
38 * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
39 * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
40 * an enum in /usr/include/rpcsvc/nis.h.
43 #if defined(GROUP)
44 #undef GROUP
45 #endif
47 #if defined(GROUP_OBJ)
48 #undef GROUP_OBJ
49 #endif
51 #endif /* BROKEN_NISPLUS_INCLUDE_FILES */
53 #include <rpcsvc/nis.h>
55 #endif /* WITH_NISPLUS_HOME */
56 #endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
58 static enum protocol_types Protocol = PROTOCOL_COREPLUS;
60 enum protocol_types get_Protocol(void)
62 return Protocol;
65 void set_Protocol(enum protocol_types p)
67 Protocol = p;
70 static enum remote_arch_types ra_type = RA_UNKNOWN;
72 /***********************************************************************
73 Definitions for all names.
74 ***********************************************************************/
76 static char *smb_myname;
77 static char *smb_myworkgroup;
78 static char *smb_scope;
79 static int smb_num_netbios_names;
80 static char **smb_my_netbios_names;
82 /***********************************************************************
83 Allocate and set myname. Ensure upper case.
84 ***********************************************************************/
86 bool set_global_myname(const char *myname)
88 SAFE_FREE(smb_myname);
89 smb_myname = SMB_STRDUP(myname);
90 if (!smb_myname)
91 return False;
92 strupper_m(smb_myname);
93 return True;
96 const char *global_myname(void)
98 return smb_myname;
101 /***********************************************************************
102 Allocate and set myworkgroup. Ensure upper case.
103 ***********************************************************************/
105 bool set_global_myworkgroup(const char *myworkgroup)
107 SAFE_FREE(smb_myworkgroup);
108 smb_myworkgroup = SMB_STRDUP(myworkgroup);
109 if (!smb_myworkgroup)
110 return False;
111 strupper_m(smb_myworkgroup);
112 return True;
115 const char *lp_workgroup(void)
117 return smb_myworkgroup;
120 /***********************************************************************
121 Allocate and set scope. Ensure upper case.
122 ***********************************************************************/
124 bool set_global_scope(const char *scope)
126 SAFE_FREE(smb_scope);
127 smb_scope = SMB_STRDUP(scope);
128 if (!smb_scope)
129 return False;
130 strupper_m(smb_scope);
131 return True;
134 /*********************************************************************
135 Ensure scope is never null string.
136 *********************************************************************/
138 const char *global_scope(void)
140 if (!smb_scope)
141 set_global_scope("");
142 return smb_scope;
145 static void free_netbios_names_array(void)
147 int i;
149 for (i = 0; i < smb_num_netbios_names; i++)
150 SAFE_FREE(smb_my_netbios_names[i]);
152 SAFE_FREE(smb_my_netbios_names);
153 smb_num_netbios_names = 0;
156 static bool allocate_my_netbios_names_array(size_t number)
158 free_netbios_names_array();
160 smb_num_netbios_names = number + 1;
161 smb_my_netbios_names = SMB_MALLOC_ARRAY( char *, smb_num_netbios_names );
163 if (!smb_my_netbios_names)
164 return False;
166 memset(smb_my_netbios_names, '\0', sizeof(char *) * smb_num_netbios_names);
167 return True;
170 static bool set_my_netbios_names(const char *name, int i)
172 SAFE_FREE(smb_my_netbios_names[i]);
174 smb_my_netbios_names[i] = SMB_STRDUP(name);
175 if (!smb_my_netbios_names[i])
176 return False;
177 strupper_m(smb_my_netbios_names[i]);
178 return True;
181 /***********************************************************************
182 Free memory allocated to global objects
183 ***********************************************************************/
185 void gfree_names(void)
187 SAFE_FREE( smb_myname );
188 SAFE_FREE( smb_myworkgroup );
189 SAFE_FREE( smb_scope );
190 free_netbios_names_array();
191 free_local_machine_name();
194 void gfree_all( void )
196 gfree_names();
197 gfree_loadparm();
198 gfree_case_tables();
199 gfree_charcnv();
200 gfree_interfaces();
201 gfree_debugsyms();
204 const char *my_netbios_names(int i)
206 return smb_my_netbios_names[i];
209 bool set_netbios_aliases(const char **str_array)
211 size_t namecount;
213 /* Work out the max number of netbios aliases that we have */
214 for( namecount=0; str_array && (str_array[namecount] != NULL); namecount++ )
217 if ( global_myname() && *global_myname())
218 namecount++;
220 /* Allocate space for the netbios aliases */
221 if (!allocate_my_netbios_names_array(namecount))
222 return False;
224 /* Use the global_myname string first */
225 namecount=0;
226 if ( global_myname() && *global_myname()) {
227 set_my_netbios_names( global_myname(), namecount );
228 namecount++;
231 if (str_array) {
232 size_t i;
233 for ( i = 0; str_array[i] != NULL; i++) {
234 size_t n;
235 bool duplicate = False;
237 /* Look for duplicates */
238 for( n=0; n<namecount; n++ ) {
239 if( strequal( str_array[i], my_netbios_names(n) ) ) {
240 duplicate = True;
241 break;
244 if (!duplicate) {
245 if (!set_my_netbios_names(str_array[i], namecount))
246 return False;
247 namecount++;
251 return True;
254 /****************************************************************************
255 Common name initialization code.
256 ****************************************************************************/
258 bool init_names(void)
260 int n;
262 if (global_myname() == NULL || *global_myname() == '\0') {
263 if (!set_global_myname(myhostname())) {
264 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
265 return False;
269 if (!set_netbios_aliases(lp_netbios_aliases())) {
270 DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
271 return False;
274 set_local_machine_name(global_myname(),false);
276 DEBUG( 5, ("Netbios name list:-\n") );
277 for( n=0; my_netbios_names(n); n++ ) {
278 DEBUGADD( 5, ("my_netbios_names[%d]=\"%s\"\n",
279 n, my_netbios_names(n) ) );
282 return( True );
285 /**************************************************************************n
286 Code to cope with username/password auth options from the commandline.
287 Used mainly in client tools.
288 ****************************************************************************/
290 struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
292 struct user_auth_info *result;
294 result = TALLOC_ZERO_P(mem_ctx, struct user_auth_info);
295 if (result == NULL) {
296 return NULL;
299 result->signing_state = Undefined;
300 return result;
303 const char *get_cmdline_auth_info_username(const struct user_auth_info *auth_info)
305 if (!auth_info->username) {
306 return "";
308 return auth_info->username;
311 void set_cmdline_auth_info_username(struct user_auth_info *auth_info,
312 const char *username)
314 TALLOC_FREE(auth_info->username);
315 auth_info->username = talloc_strdup(auth_info, username);
316 if (!auth_info->username) {
317 exit(ENOMEM);
321 const char *get_cmdline_auth_info_domain(const struct user_auth_info *auth_info)
323 if (!auth_info->domain) {
324 return "";
326 return auth_info->domain;
329 void set_cmdline_auth_info_domain(struct user_auth_info *auth_info,
330 const char *domain)
332 TALLOC_FREE(auth_info->domain);
333 auth_info->domain = talloc_strdup(auth_info, domain);
334 if (!auth_info->domain) {
335 exit(ENOMEM);
339 const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_info)
341 if (!auth_info->password) {
342 return "";
344 return auth_info->password;
347 void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
348 const char *password)
350 TALLOC_FREE(auth_info->password);
351 if (password == NULL) {
352 password = "";
354 auth_info->password = talloc_strdup(auth_info, password);
355 if (!auth_info->password) {
356 exit(ENOMEM);
358 auth_info->got_pass = true;
361 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
362 const char *arg)
364 auth_info->signing_state = -1;
365 if (strequal(arg, "off") || strequal(arg, "no") ||
366 strequal(arg, "false")) {
367 auth_info->signing_state = false;
368 } else if (strequal(arg, "on") || strequal(arg, "yes") ||
369 strequal(arg, "true") || strequal(arg, "auto")) {
370 auth_info->signing_state = true;
371 } else if (strequal(arg, "force") || strequal(arg, "required") ||
372 strequal(arg, "forced")) {
373 auth_info->signing_state = Required;
374 } else {
375 return false;
377 return true;
380 int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
382 return auth_info->signing_state;
385 void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
386 bool b)
388 auth_info->use_kerberos = b;
391 bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info)
393 return auth_info->use_kerberos;
396 void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_info,
397 bool b)
399 auth_info->fallback_after_kerberos = b;
402 bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *auth_info)
404 return auth_info->fallback_after_kerberos;
407 /* This should only be used by lib/popt_common.c JRA */
408 void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
410 auth_info->use_kerberos = true;
411 auth_info->got_pass = true;
414 /* This should only be used by lib/popt_common.c JRA */
415 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
417 auth_info->smb_encrypt = true;
420 void set_cmdline_auth_info_use_machine_account(struct user_auth_info *auth_info)
422 auth_info->use_machine_account = true;
425 bool get_cmdline_auth_info_got_pass(const struct user_auth_info *auth_info)
427 return auth_info->got_pass;
430 bool get_cmdline_auth_info_smb_encrypt(const struct user_auth_info *auth_info)
432 return auth_info->smb_encrypt;
435 bool get_cmdline_auth_info_use_machine_account(const struct user_auth_info *auth_info)
437 return auth_info->use_machine_account;
440 struct user_auth_info *get_cmdline_auth_info_copy(TALLOC_CTX *mem_ctx,
441 const struct user_auth_info *src)
443 struct user_auth_info *result;
445 result = user_auth_info_init(mem_ctx);
446 if (result == NULL) {
447 return NULL;
450 *result = *src;
452 result->username = talloc_strdup(
453 result, get_cmdline_auth_info_username(src));
454 result->password = talloc_strdup(
455 result, get_cmdline_auth_info_password(src));
456 if ((result->username == NULL) || (result->password == NULL)) {
457 TALLOC_FREE(result);
458 return NULL;
461 return result;
464 bool set_cmdline_auth_info_machine_account_creds(struct user_auth_info *auth_info)
466 char *pass = NULL;
467 char *account = NULL;
469 if (!get_cmdline_auth_info_use_machine_account(auth_info)) {
470 return false;
473 if (!secrets_init()) {
474 d_printf("ERROR: Unable to open secrets database\n");
475 return false;
478 if (asprintf(&account, "%s$@%s", global_myname(), lp_realm()) < 0) {
479 return false;
482 pass = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
483 if (!pass) {
484 d_printf("ERROR: Unable to fetch machine password for "
485 "%s in domain %s\n",
486 account, lp_workgroup());
487 SAFE_FREE(account);
488 return false;
491 set_cmdline_auth_info_username(auth_info, account);
492 set_cmdline_auth_info_password(auth_info, pass);
494 SAFE_FREE(account);
495 SAFE_FREE(pass);
497 return true;
500 /****************************************************************************
501 Ensure we have a password if one not given.
502 ****************************************************************************/
504 void set_cmdline_auth_info_getpass(struct user_auth_info *auth_info)
506 char *label = NULL;
507 char *pass;
508 TALLOC_CTX *frame;
510 if (get_cmdline_auth_info_got_pass(auth_info) ||
511 get_cmdline_auth_info_use_kerberos(auth_info)) {
512 /* Already got one... */
513 return;
516 frame = talloc_stackframe();
517 label = talloc_asprintf(frame, "Enter %s's password: ",
518 get_cmdline_auth_info_username(auth_info));
519 pass = getpass(label);
520 if (pass) {
521 set_cmdline_auth_info_password(auth_info, pass);
523 TALLOC_FREE(frame);
526 /*******************************************************************
527 Check if a file exists - call vfs_file_exist for samba files.
528 ********************************************************************/
530 bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf,
531 bool fake_dir_create_times)
533 SMB_STRUCT_STAT st;
534 if (!sbuf)
535 sbuf = &st;
537 if (sys_stat(fname, sbuf, fake_dir_create_times) != 0)
538 return(False);
540 return((S_ISREG(sbuf->st_ex_mode)) || (S_ISFIFO(sbuf->st_ex_mode)));
543 /*******************************************************************
544 Check if a unix domain socket exists - call vfs_file_exist for samba files.
545 ********************************************************************/
547 bool socket_exist(const char *fname)
549 SMB_STRUCT_STAT st;
550 if (sys_stat(fname, &st, false) != 0)
551 return(False);
553 return S_ISSOCK(st.st_ex_mode);
556 /*******************************************************************
557 Returns the size in bytes of the named given the stat struct.
558 ********************************************************************/
560 uint64_t get_file_size_stat(const SMB_STRUCT_STAT *sbuf)
562 return sbuf->st_ex_size;
565 /*******************************************************************
566 Returns the size in bytes of the named file.
567 ********************************************************************/
569 SMB_OFF_T get_file_size(char *file_name)
571 SMB_STRUCT_STAT buf;
572 buf.st_ex_size = 0;
573 if (sys_stat(file_name, &buf, false) != 0)
574 return (SMB_OFF_T)-1;
575 return get_file_size_stat(&buf);
578 /*******************************************************************
579 Return a string representing an attribute for a file.
580 ********************************************************************/
582 char *attrib_string(uint16 mode)
584 fstring attrstr;
586 attrstr[0] = 0;
588 if (mode & aVOLID) fstrcat(attrstr,"V");
589 if (mode & aDIR) fstrcat(attrstr,"D");
590 if (mode & aARCH) fstrcat(attrstr,"A");
591 if (mode & aHIDDEN) fstrcat(attrstr,"H");
592 if (mode & aSYSTEM) fstrcat(attrstr,"S");
593 if (mode & aRONLY) fstrcat(attrstr,"R");
595 return talloc_strdup(talloc_tos(), attrstr);
598 /*******************************************************************
599 Show a smb message structure.
600 ********************************************************************/
602 void show_msg(char *buf)
604 int i;
605 int bcc=0;
607 if (!DEBUGLVL(5))
608 return;
610 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
611 smb_len(buf),
612 (int)CVAL(buf,smb_com),
613 (int)CVAL(buf,smb_rcls),
614 (int)CVAL(buf,smb_reh),
615 (int)SVAL(buf,smb_err),
616 (int)CVAL(buf,smb_flg),
617 (int)SVAL(buf,smb_flg2)));
618 DEBUGADD(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\n",
619 (int)SVAL(buf,smb_tid),
620 (int)SVAL(buf,smb_pid),
621 (int)SVAL(buf,smb_uid),
622 (int)SVAL(buf,smb_mid)));
623 DEBUGADD(5,("smt_wct=%d\n",(int)CVAL(buf,smb_wct)));
625 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
626 DEBUGADD(5,("smb_vwv[%2d]=%5d (0x%X)\n",i,
627 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
629 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
631 DEBUGADD(5,("smb_bcc=%d\n",bcc));
633 if (DEBUGLEVEL < 10)
634 return;
636 if (DEBUGLEVEL < 50)
637 bcc = MIN(bcc, 512);
639 dump_data(10, (uint8 *)smb_buf(buf), bcc);
642 /*******************************************************************
643 Set the length and marker of an encrypted smb packet.
644 ********************************************************************/
646 void smb_set_enclen(char *buf,int len,uint16 enc_ctx_num)
648 _smb_setlen(buf,len);
650 SCVAL(buf,4,0xFF);
651 SCVAL(buf,5,'E');
652 SSVAL(buf,6,enc_ctx_num);
655 /*******************************************************************
656 Set the length and marker of an smb packet.
657 ********************************************************************/
659 void smb_setlen(char *buf,int len)
661 _smb_setlen(buf,len);
663 SCVAL(buf,4,0xFF);
664 SCVAL(buf,5,'S');
665 SCVAL(buf,6,'M');
666 SCVAL(buf,7,'B');
669 /*******************************************************************
670 Setup only the byte count for a smb message.
671 ********************************************************************/
673 int set_message_bcc(char *buf,int num_bytes)
675 int num_words = CVAL(buf,smb_wct);
676 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
677 _smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
678 return (smb_size + num_words*2 + num_bytes);
681 /*******************************************************************
682 Add a data blob to the end of a smb_buf, adjusting bcc and smb_len.
683 Return the bytes added
684 ********************************************************************/
686 ssize_t message_push_blob(uint8 **outbuf, DATA_BLOB blob)
688 size_t newlen = smb_len(*outbuf) + 4 + blob.length;
689 uint8 *tmp;
691 if (!(tmp = TALLOC_REALLOC_ARRAY(NULL, *outbuf, uint8, newlen))) {
692 DEBUG(0, ("talloc failed\n"));
693 return -1;
695 *outbuf = tmp;
697 memcpy(tmp + smb_len(tmp) + 4, blob.data, blob.length);
698 set_message_bcc((char *)tmp, smb_buflen(tmp) + blob.length);
699 return blob.length;
702 /*******************************************************************
703 Reduce a file name, removing .. elements.
704 ********************************************************************/
706 static char *dos_clean_name(TALLOC_CTX *ctx, const char *s)
708 char *p = NULL;
709 char *str = NULL;
711 DEBUG(3,("dos_clean_name [%s]\n",s));
713 /* remove any double slashes */
714 str = talloc_all_string_sub(ctx, s, "\\\\", "\\");
715 if (!str) {
716 return NULL;
719 /* Remove leading .\\ characters */
720 if(strncmp(str, ".\\", 2) == 0) {
721 trim_string(str, ".\\", NULL);
722 if(*str == 0) {
723 str = talloc_strdup(ctx, ".\\");
724 if (!str) {
725 return NULL;
730 while ((p = strstr_m(str,"\\..\\")) != NULL) {
731 char *s1;
733 *p = 0;
734 s1 = p+3;
736 if ((p=strrchr_m(str,'\\')) != NULL) {
737 *p = 0;
738 } else {
739 *str = 0;
741 str = talloc_asprintf(ctx,
742 "%s%s",
743 str,
744 s1);
745 if (!str) {
746 return NULL;
750 trim_string(str,NULL,"\\..");
751 return talloc_all_string_sub(ctx, str, "\\.\\", "\\");
754 /*******************************************************************
755 Reduce a file name, removing .. elements.
756 ********************************************************************/
758 char *unix_clean_name(TALLOC_CTX *ctx, const char *s)
760 char *p = NULL;
761 char *str = NULL;
763 DEBUG(3,("unix_clean_name [%s]\n",s));
765 /* remove any double slashes */
766 str = talloc_all_string_sub(ctx, s, "//","/");
767 if (!str) {
768 return NULL;
771 /* Remove leading ./ characters */
772 if(strncmp(str, "./", 2) == 0) {
773 trim_string(str, "./", NULL);
774 if(*str == 0) {
775 str = talloc_strdup(ctx, "./");
776 if (!str) {
777 return NULL;
782 while ((p = strstr_m(str,"/../")) != NULL) {
783 char *s1;
785 *p = 0;
786 s1 = p+3;
788 if ((p=strrchr_m(str,'/')) != NULL) {
789 *p = 0;
790 } else {
791 *str = 0;
793 str = talloc_asprintf(ctx,
794 "%s%s",
795 str,
796 s1);
797 if (!str) {
798 return NULL;
802 trim_string(str,NULL,"/..");
803 return talloc_all_string_sub(ctx, str, "/./", "/");
806 char *clean_name(TALLOC_CTX *ctx, const char *s)
808 char *str = dos_clean_name(ctx, s);
809 if (!str) {
810 return NULL;
812 return unix_clean_name(ctx, str);
815 /*******************************************************************
816 Write data into an fd at a given offset. Ignore seek errors.
817 ********************************************************************/
819 ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos)
821 size_t total=0;
822 ssize_t ret;
824 if (pos == (SMB_OFF_T)-1) {
825 return write_data(fd, buffer, N);
827 #if defined(HAVE_PWRITE) || defined(HAVE_PRWITE64)
828 while (total < N) {
829 ret = sys_pwrite(fd,buffer + total,N - total, pos);
830 if (ret == -1 && errno == ESPIPE) {
831 return write_data(fd, buffer + total,N - total);
833 if (ret == -1) {
834 DEBUG(0,("write_data_at_offset: write failure. Error = %s\n", strerror(errno) ));
835 return -1;
837 if (ret == 0) {
838 return total;
840 total += ret;
841 pos += ret;
843 return (ssize_t)total;
844 #else
845 /* Use lseek and write_data. */
846 if (sys_lseek(fd, pos, SEEK_SET) == -1) {
847 if (errno != ESPIPE) {
848 return -1;
851 return write_data(fd, buffer, N);
852 #endif
855 /*******************************************************************
856 Sleep for a specified number of milliseconds.
857 ********************************************************************/
859 void smb_msleep(unsigned int t)
861 #if defined(HAVE_NANOSLEEP)
862 struct timespec tval;
863 int ret;
865 tval.tv_sec = t/1000;
866 tval.tv_nsec = 1000000*(t%1000);
868 do {
869 errno = 0;
870 ret = nanosleep(&tval, &tval);
871 } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0));
872 #else
873 unsigned int tdiff=0;
874 struct timeval tval,t1,t2;
875 fd_set fds;
877 GetTimeOfDay(&t1);
878 t2 = t1;
880 while (tdiff < t) {
881 tval.tv_sec = (t-tdiff)/1000;
882 tval.tv_usec = 1000*((t-tdiff)%1000);
884 /* Never wait for more than 1 sec. */
885 if (tval.tv_sec > 1) {
886 tval.tv_sec = 1;
887 tval.tv_usec = 0;
890 FD_ZERO(&fds);
891 errno = 0;
892 sys_select_intr(0,&fds,NULL,NULL,&tval);
894 GetTimeOfDay(&t2);
895 if (t2.tv_sec < t1.tv_sec) {
896 /* Someone adjusted time... */
897 t1 = t2;
900 tdiff = TvalDiff(&t1,&t2);
902 #endif
905 NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx,
906 struct event_context *ev_ctx,
907 bool parent_longlived)
909 NTSTATUS status = NT_STATUS_OK;
911 /* Reset the state of the random
912 * number generation system, so
913 * children do not get the same random
914 * numbers as each other */
915 set_need_random_reseed();
917 /* tdb needs special fork handling */
918 if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
919 DEBUG(0,("tdb_reopen_all failed.\n"));
920 status = NT_STATUS_OPEN_FAILED;
921 goto done;
924 if (ev_ctx) {
925 event_context_reinit(ev_ctx);
928 if (msg_ctx) {
930 * For clustering, we need to re-init our ctdbd connection after the
931 * fork
933 status = messaging_reinit(msg_ctx);
934 if (!NT_STATUS_IS_OK(status)) {
935 DEBUG(0,("messaging_reinit() failed: %s\n",
936 nt_errstr(status)));
939 done:
940 return status;
943 /****************************************************************************
944 Put up a yes/no prompt.
945 ****************************************************************************/
947 bool yesno(const char *p)
949 char ans[20];
950 printf("%s",p);
952 if (!fgets(ans,sizeof(ans)-1,stdin))
953 return(False);
955 if (*ans == 'y' || *ans == 'Y')
956 return(True);
958 return(False);
961 #if defined(PARANOID_MALLOC_CHECKER)
963 /****************************************************************************
964 Internal malloc wrapper. Externally visible.
965 ****************************************************************************/
967 void *malloc_(size_t size)
969 if (size == 0) {
970 return NULL;
972 #undef malloc
973 return malloc(size);
974 #define malloc(s) __ERROR_DONT_USE_MALLOC_DIRECTLY
977 /****************************************************************************
978 Internal calloc wrapper. Not externally visible.
979 ****************************************************************************/
981 static void *calloc_(size_t count, size_t size)
983 if (size == 0 || count == 0) {
984 return NULL;
986 #undef calloc
987 return calloc(count, size);
988 #define calloc(n,s) __ERROR_DONT_USE_CALLOC_DIRECTLY
991 /****************************************************************************
992 Internal realloc wrapper. Not externally visible.
993 ****************************************************************************/
995 static void *realloc_(void *ptr, size_t size)
997 #undef realloc
998 return realloc(ptr, size);
999 #define realloc(p,s) __ERROR_DONT_USE_RELLOC_DIRECTLY
1002 #endif /* PARANOID_MALLOC_CHECKER */
1004 /****************************************************************************
1005 Type-safe memalign
1006 ****************************************************************************/
1008 void *memalign_array(size_t el_size, size_t align, unsigned int count)
1010 if (count >= MAX_ALLOC_SIZE/el_size) {
1011 return NULL;
1014 return sys_memalign(align, el_size*count);
1017 /****************************************************************************
1018 Type-safe calloc.
1019 ****************************************************************************/
1021 void *calloc_array(size_t size, size_t nmemb)
1023 if (nmemb >= MAX_ALLOC_SIZE/size) {
1024 return NULL;
1026 if (size == 0 || nmemb == 0) {
1027 return NULL;
1029 #if defined(PARANOID_MALLOC_CHECKER)
1030 return calloc_(nmemb, size);
1031 #else
1032 return calloc(nmemb, size);
1033 #endif
1036 /****************************************************************************
1037 Expand a pointer to be a particular size.
1038 Note that this version of Realloc has an extra parameter that decides
1039 whether to free the passed in storage on allocation failure or if the
1040 new size is zero.
1042 This is designed for use in the typical idiom of :
1044 p = SMB_REALLOC(p, size)
1045 if (!p) {
1046 return error;
1049 and not to have to keep track of the old 'p' contents to free later, nor
1050 to worry if the size parameter was zero. In the case where NULL is returned
1051 we guarentee that p has been freed.
1053 If free later semantics are desired, then pass 'free_old_on_error' as False which
1054 guarentees that the old contents are not freed on error, even if size == 0. To use
1055 this idiom use :
1057 tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size);
1058 if (!tmp) {
1059 SAFE_FREE(p);
1060 return error;
1061 } else {
1062 p = tmp;
1065 Changes were instigated by Coverity error checking. JRA.
1066 ****************************************************************************/
1068 void *Realloc(void *p, size_t size, bool free_old_on_error)
1070 void *ret=NULL;
1072 if (size == 0) {
1073 if (free_old_on_error) {
1074 SAFE_FREE(p);
1076 DEBUG(2,("Realloc asked for 0 bytes\n"));
1077 return NULL;
1080 #if defined(PARANOID_MALLOC_CHECKER)
1081 if (!p) {
1082 ret = (void *)malloc_(size);
1083 } else {
1084 ret = (void *)realloc_(p,size);
1086 #else
1087 if (!p) {
1088 ret = (void *)malloc(size);
1089 } else {
1090 ret = (void *)realloc(p,size);
1092 #endif
1094 if (!ret) {
1095 if (free_old_on_error && p) {
1096 SAFE_FREE(p);
1098 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
1101 return(ret);
1104 /****************************************************************************
1105 (Hopefully) efficient array append.
1106 ****************************************************************************/
1108 void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size,
1109 void *element, void *_array, uint32 *num_elements,
1110 ssize_t *array_size)
1112 void **array = (void **)_array;
1114 if (*array_size < 0) {
1115 return;
1118 if (*array == NULL) {
1119 if (*array_size == 0) {
1120 *array_size = 128;
1123 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1124 goto error;
1127 *array = TALLOC(mem_ctx, element_size * (*array_size));
1128 if (*array == NULL) {
1129 goto error;
1133 if (*num_elements == *array_size) {
1134 *array_size *= 2;
1136 if (*array_size >= MAX_ALLOC_SIZE/element_size) {
1137 goto error;
1140 *array = TALLOC_REALLOC(mem_ctx, *array,
1141 element_size * (*array_size));
1143 if (*array == NULL) {
1144 goto error;
1148 memcpy((char *)(*array) + element_size*(*num_elements),
1149 element, element_size);
1150 *num_elements += 1;
1152 return;
1154 error:
1155 *num_elements = 0;
1156 *array_size = -1;
1159 /****************************************************************************
1160 Get my own domain name, or "" if we have none.
1161 ****************************************************************************/
1163 char *get_mydnsdomname(TALLOC_CTX *ctx)
1165 const char *domname;
1166 char *p;
1168 domname = get_mydnsfullname();
1169 if (!domname) {
1170 return NULL;
1173 p = strchr_m(domname, '.');
1174 if (p) {
1175 p++;
1176 return talloc_strdup(ctx, p);
1177 } else {
1178 return talloc_strdup(ctx, "");
1182 /****************************************************************************
1183 Interpret a protocol description string, with a default.
1184 ****************************************************************************/
1186 int interpret_protocol(const char *str,int def)
1188 if (strequal(str,"NT1"))
1189 return(PROTOCOL_NT1);
1190 if (strequal(str,"LANMAN2"))
1191 return(PROTOCOL_LANMAN2);
1192 if (strequal(str,"LANMAN1"))
1193 return(PROTOCOL_LANMAN1);
1194 if (strequal(str,"CORE"))
1195 return(PROTOCOL_CORE);
1196 if (strequal(str,"COREPLUS"))
1197 return(PROTOCOL_COREPLUS);
1198 if (strequal(str,"CORE+"))
1199 return(PROTOCOL_COREPLUS);
1201 DEBUG(0,("Unrecognised protocol level %s\n",str));
1203 return(def);
1207 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1208 /******************************************************************
1209 Remove any mount options such as -rsize=2048,wsize=2048 etc.
1210 Based on a fix from <Thomas.Hepper@icem.de>.
1211 Returns a malloc'ed string.
1212 *******************************************************************/
1214 static char *strip_mount_options(TALLOC_CTX *ctx, const char *str)
1216 if (*str == '-') {
1217 const char *p = str;
1218 while(*p && !isspace(*p))
1219 p++;
1220 while(*p && isspace(*p))
1221 p++;
1222 if(*p) {
1223 return talloc_strdup(ctx, p);
1226 return NULL;
1229 /*******************************************************************
1230 Patch from jkf@soton.ac.uk
1231 Split Luke's automount_server into YP lookup and string splitter
1232 so can easily implement automount_path().
1233 Returns a malloc'ed string.
1234 *******************************************************************/
1236 #ifdef WITH_NISPLUS_HOME
1237 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1239 char *value = NULL;
1241 char *nis_map = (char *)lp_nis_home_map_name();
1243 char buffer[NIS_MAXATTRVAL + 1];
1244 nis_result *result;
1245 nis_object *object;
1246 entry_obj *entry;
1248 snprintf(buffer, sizeof(buffer), "[key=%s],%s", user_name, nis_map);
1249 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
1251 if (result = nis_list(buffer, FOLLOW_PATH|EXPAND_NAME|HARD_LOOKUP, NULL, NULL)) {
1252 if (result->status != NIS_SUCCESS) {
1253 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
1254 } else {
1255 object = result->objects.objects_val;
1256 if (object->zo_data.zo_type == ENTRY_OBJ) {
1257 entry = &object->zo_data.objdata_u.en_data;
1258 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
1259 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
1261 value = talloc_strdup(ctx,
1262 entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
1263 if (!value) {
1264 nis_freeresult(result);
1265 return NULL;
1267 value = talloc_string_sub(ctx,
1268 value,
1269 "&",
1270 user_name);
1274 nis_freeresult(result);
1276 if (value) {
1277 value = strip_mount_options(ctx, value);
1278 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n",
1279 user_name, value));
1281 return value;
1283 #else /* WITH_NISPLUS_HOME */
1285 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name)
1287 char *value = NULL;
1289 int nis_error; /* returned by yp all functions */
1290 char *nis_result; /* yp_match inits this */
1291 int nis_result_len; /* and set this */
1292 char *nis_domain; /* yp_get_default_domain inits this */
1293 char *nis_map = (char *)lp_nis_home_map_name();
1295 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) {
1296 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
1297 return NULL;
1300 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
1302 if ((nis_error = yp_match(nis_domain, nis_map, user_name,
1303 strlen(user_name), &nis_result,
1304 &nis_result_len)) == 0) {
1305 value = talloc_strdup(ctx, nis_result);
1306 if (!value) {
1307 return NULL;
1309 value = strip_mount_options(ctx, value);
1310 } else if(nis_error == YPERR_KEY) {
1311 DEBUG(3, ("YP Key not found: while looking up \"%s\" in map \"%s\"\n",
1312 user_name, nis_map));
1313 DEBUG(3, ("using defaults for server and home directory\n"));
1314 } else {
1315 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
1316 yperr_string(nis_error), user_name, nis_map));
1319 if (value) {
1320 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, value));
1322 return value;
1324 #endif /* WITH_NISPLUS_HOME */
1325 #endif
1327 /****************************************************************************
1328 Check if a process exists. Does this work on all unixes?
1329 ****************************************************************************/
1331 bool process_exists(const struct server_id pid)
1333 if (procid_is_me(&pid)) {
1334 return True;
1337 if (procid_is_local(&pid)) {
1338 return (kill(pid.pid,0) == 0 || errno != ESRCH);
1341 #ifdef CLUSTER_SUPPORT
1342 return ctdbd_process_exists(messaging_ctdbd_connection(), pid.vnn,
1343 pid.pid);
1344 #else
1345 return False;
1346 #endif
1349 /*******************************************************************
1350 Convert a uid into a user name.
1351 ********************************************************************/
1353 const char *uidtoname(uid_t uid)
1355 TALLOC_CTX *ctx = talloc_tos();
1356 char *name = NULL;
1357 struct passwd *pass = NULL;
1359 pass = getpwuid_alloc(ctx,uid);
1360 if (pass) {
1361 name = talloc_strdup(ctx,pass->pw_name);
1362 TALLOC_FREE(pass);
1363 } else {
1364 name = talloc_asprintf(ctx,
1365 "%ld",
1366 (long int)uid);
1368 return name;
1371 /*******************************************************************
1372 Convert a gid into a group name.
1373 ********************************************************************/
1375 char *gidtoname(gid_t gid)
1377 struct group *grp;
1379 grp = getgrgid(gid);
1380 if (grp) {
1381 return talloc_strdup(talloc_tos(), grp->gr_name);
1383 else {
1384 return talloc_asprintf(talloc_tos(),
1385 "%d",
1386 (int)gid);
1390 /*******************************************************************
1391 Convert a user name into a uid.
1392 ********************************************************************/
1394 uid_t nametouid(const char *name)
1396 struct passwd *pass;
1397 char *p;
1398 uid_t u;
1400 pass = getpwnam_alloc(talloc_autofree_context(), name);
1401 if (pass) {
1402 u = pass->pw_uid;
1403 TALLOC_FREE(pass);
1404 return u;
1407 u = (uid_t)strtol(name, &p, 0);
1408 if ((p != name) && (*p == '\0'))
1409 return u;
1411 return (uid_t)-1;
1414 /*******************************************************************
1415 Convert a name to a gid_t if possible. Return -1 if not a group.
1416 ********************************************************************/
1418 gid_t nametogid(const char *name)
1420 struct group *grp;
1421 char *p;
1422 gid_t g;
1424 g = (gid_t)strtol(name, &p, 0);
1425 if ((p != name) && (*p == '\0'))
1426 return g;
1428 grp = sys_getgrnam(name);
1429 if (grp)
1430 return(grp->gr_gid);
1431 return (gid_t)-1;
1434 /*******************************************************************
1435 Something really nasty happened - panic !
1436 ********************************************************************/
1438 void smb_panic(const char *const why)
1440 char *cmd;
1441 int result;
1443 #ifdef DEVELOPER
1446 if (global_clobber_region_function) {
1447 DEBUG(0,("smb_panic: clobber_region() last called from [%s(%u)]\n",
1448 global_clobber_region_function,
1449 global_clobber_region_line));
1452 #endif
1454 DEBUG(0,("PANIC (pid %llu): %s\n",
1455 (unsigned long long)sys_getpid(), why));
1456 log_stack_trace();
1458 cmd = lp_panic_action();
1459 if (cmd && *cmd) {
1460 DEBUG(0, ("smb_panic(): calling panic action [%s]\n", cmd));
1461 result = system(cmd);
1463 if (result == -1)
1464 DEBUG(0, ("smb_panic(): fork failed in panic action: %s\n",
1465 strerror(errno)));
1466 else
1467 DEBUG(0, ("smb_panic(): action returned status %d\n",
1468 WEXITSTATUS(result)));
1471 dump_core();
1474 /*******************************************************************
1475 Print a backtrace of the stack to the debug log. This function
1476 DELIBERATELY LEAKS MEMORY. The expectation is that you should
1477 exit shortly after calling it.
1478 ********************************************************************/
1480 #ifdef HAVE_LIBUNWIND_H
1481 #include <libunwind.h>
1482 #endif
1484 #ifdef HAVE_EXECINFO_H
1485 #include <execinfo.h>
1486 #endif
1488 #ifdef HAVE_LIBEXC_H
1489 #include <libexc.h>
1490 #endif
1492 void log_stack_trace(void)
1494 #ifdef HAVE_LIBUNWIND
1495 /* Try to use libunwind before any other technique since on ia64
1496 * libunwind correctly walks the stack in more circumstances than
1497 * backtrace.
1499 unw_cursor_t cursor;
1500 unw_context_t uc;
1501 unsigned i = 0;
1503 char procname[256];
1504 unw_word_t ip, sp, off;
1506 procname[sizeof(procname) - 1] = '\0';
1508 if (unw_getcontext(&uc) != 0) {
1509 goto libunwind_failed;
1512 if (unw_init_local(&cursor, &uc) != 0) {
1513 goto libunwind_failed;
1516 DEBUG(0, ("BACKTRACE:\n"));
1518 do {
1519 ip = sp = 0;
1520 unw_get_reg(&cursor, UNW_REG_IP, &ip);
1521 unw_get_reg(&cursor, UNW_REG_SP, &sp);
1523 switch (unw_get_proc_name(&cursor,
1524 procname, sizeof(procname) - 1, &off) ) {
1525 case 0:
1526 /* Name found. */
1527 case -UNW_ENOMEM:
1528 /* Name truncated. */
1529 DEBUGADD(0, (" #%u %s + %#llx [ip=%#llx] [sp=%#llx]\n",
1530 i, procname, (long long)off,
1531 (long long)ip, (long long) sp));
1532 break;
1533 default:
1534 /* case -UNW_ENOINFO: */
1535 /* case -UNW_EUNSPEC: */
1536 /* No symbol name found. */
1537 DEBUGADD(0, (" #%u %s [ip=%#llx] [sp=%#llx]\n",
1538 i, "<unknown symbol>",
1539 (long long)ip, (long long) sp));
1541 ++i;
1542 } while (unw_step(&cursor) > 0);
1544 return;
1546 libunwind_failed:
1547 DEBUG(0, ("unable to produce a stack trace with libunwind\n"));
1549 #elif HAVE_BACKTRACE_SYMBOLS
1550 void *backtrace_stack[BACKTRACE_STACK_SIZE];
1551 size_t backtrace_size;
1552 char **backtrace_strings;
1554 /* get the backtrace (stack frames) */
1555 backtrace_size = backtrace(backtrace_stack,BACKTRACE_STACK_SIZE);
1556 backtrace_strings = backtrace_symbols(backtrace_stack, backtrace_size);
1558 DEBUG(0, ("BACKTRACE: %lu stack frames:\n",
1559 (unsigned long)backtrace_size));
1561 if (backtrace_strings) {
1562 int i;
1564 for (i = 0; i < backtrace_size; i++)
1565 DEBUGADD(0, (" #%u %s\n", i, backtrace_strings[i]));
1567 /* Leak the backtrace_strings, rather than risk what free() might do */
1570 #elif HAVE_LIBEXC
1572 /* The IRIX libexc library provides an API for unwinding the stack. See
1573 * libexc(3) for details. Apparantly trace_back_stack leaks memory, but
1574 * since we are about to abort anyway, it hardly matters.
1577 #define NAMESIZE 32 /* Arbitrary */
1579 __uint64_t addrs[BACKTRACE_STACK_SIZE];
1580 char * names[BACKTRACE_STACK_SIZE];
1581 char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE];
1583 int i;
1584 int levels;
1586 ZERO_ARRAY(addrs);
1587 ZERO_ARRAY(names);
1588 ZERO_ARRAY(namebuf);
1590 /* We need to be root so we can open our /proc entry to walk
1591 * our stack. It also helps when we want to dump core.
1593 become_root();
1595 for (i = 0; i < BACKTRACE_STACK_SIZE; i++) {
1596 names[i] = namebuf + (i * NAMESIZE);
1599 levels = trace_back_stack(0, addrs, names,
1600 BACKTRACE_STACK_SIZE, NAMESIZE - 1);
1602 DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels));
1603 for (i = 0; i < levels; i++) {
1604 DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i]));
1606 #undef NAMESIZE
1608 #else
1609 DEBUG(0, ("unable to produce a stack trace on this platform\n"));
1610 #endif
1613 /*******************************************************************
1614 A readdir wrapper which just returns the file name.
1615 ********************************************************************/
1617 const char *readdirname(SMB_STRUCT_DIR *p)
1619 SMB_STRUCT_DIRENT *ptr;
1620 char *dname;
1622 if (!p)
1623 return(NULL);
1625 ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
1626 if (!ptr)
1627 return(NULL);
1629 dname = ptr->d_name;
1631 #ifdef NEXT2
1632 if (telldir(p) < 0)
1633 return(NULL);
1634 #endif
1636 #ifdef HAVE_BROKEN_READDIR_NAME
1637 /* using /usr/ucb/cc is BAD */
1638 dname = dname - 2;
1639 #endif
1641 return talloc_strdup(talloc_tos(), dname);
1644 /*******************************************************************
1645 Utility function used to decide if the last component
1646 of a path matches a (possibly wildcarded) entry in a namelist.
1647 ********************************************************************/
1649 bool is_in_path(const char *name, name_compare_entry *namelist, bool case_sensitive)
1651 const char *last_component;
1653 /* if we have no list it's obviously not in the path */
1654 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) {
1655 return False;
1658 DEBUG(8, ("is_in_path: %s\n", name));
1660 /* Get the last component of the unix name. */
1661 last_component = strrchr_m(name, '/');
1662 if (!last_component) {
1663 last_component = name;
1664 } else {
1665 last_component++; /* Go past '/' */
1668 for(; namelist->name != NULL; namelist++) {
1669 if(namelist->is_wild) {
1670 if (mask_match(last_component, namelist->name, case_sensitive)) {
1671 DEBUG(8,("is_in_path: mask match succeeded\n"));
1672 return True;
1674 } else {
1675 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
1676 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) {
1677 DEBUG(8,("is_in_path: match succeeded\n"));
1678 return True;
1682 DEBUG(8,("is_in_path: match not found\n"));
1683 return False;
1686 /*******************************************************************
1687 Strip a '/' separated list into an array of
1688 name_compare_enties structures suitable for
1689 passing to is_in_path(). We do this for
1690 speed so we can pre-parse all the names in the list
1691 and don't do it for each call to is_in_path().
1692 namelist is modified here and is assumed to be
1693 a copy owned by the caller.
1694 We also check if the entry contains a wildcard to
1695 remove a potentially expensive call to mask_match
1696 if possible.
1697 ********************************************************************/
1699 void set_namearray(name_compare_entry **ppname_array, const char *namelist)
1701 char *name_end;
1702 char *nameptr = (char *)namelist;
1703 int num_entries = 0;
1704 int i;
1706 (*ppname_array) = NULL;
1708 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
1709 return;
1711 /* We need to make two passes over the string. The
1712 first to count the number of elements, the second
1713 to split it.
1716 while(*nameptr) {
1717 if ( *nameptr == '/' ) {
1718 /* cope with multiple (useless) /s) */
1719 nameptr++;
1720 continue;
1722 /* anything left? */
1723 if ( *nameptr == '\0' )
1724 break;
1726 /* find the next '/' or consume remaining */
1727 name_end = strchr_m(nameptr, '/');
1728 if (name_end == NULL)
1729 name_end = (char *)nameptr + strlen(nameptr);
1731 /* next segment please */
1732 nameptr = name_end + 1;
1733 num_entries++;
1736 if(num_entries == 0)
1737 return;
1739 if(( (*ppname_array) = SMB_MALLOC_ARRAY(name_compare_entry, num_entries + 1)) == NULL) {
1740 DEBUG(0,("set_namearray: malloc fail\n"));
1741 return;
1744 /* Now copy out the names */
1745 nameptr = (char *)namelist;
1746 i = 0;
1747 while(*nameptr) {
1748 if ( *nameptr == '/' ) {
1749 /* cope with multiple (useless) /s) */
1750 nameptr++;
1751 continue;
1753 /* anything left? */
1754 if ( *nameptr == '\0' )
1755 break;
1757 /* find the next '/' or consume remaining */
1758 name_end = strchr_m(nameptr, '/');
1759 if (name_end)
1760 *name_end = '\0';
1761 else
1762 name_end = nameptr + strlen(nameptr);
1764 (*ppname_array)[i].is_wild = ms_has_wild(nameptr);
1765 if(((*ppname_array)[i].name = SMB_STRDUP(nameptr)) == NULL) {
1766 DEBUG(0,("set_namearray: malloc fail (1)\n"));
1767 return;
1770 /* next segment please */
1771 nameptr = name_end + 1;
1772 i++;
1775 (*ppname_array)[i].name = NULL;
1777 return;
1780 /****************************************************************************
1781 Routine to free a namearray.
1782 ****************************************************************************/
1784 void free_namearray(name_compare_entry *name_array)
1786 int i;
1788 if(name_array == NULL)
1789 return;
1791 for(i=0; name_array[i].name!=NULL; i++)
1792 SAFE_FREE(name_array[i].name);
1793 SAFE_FREE(name_array);
1796 #undef DBGC_CLASS
1797 #define DBGC_CLASS DBGC_LOCKING
1799 /****************************************************************************
1800 Simple routine to query existing file locks. Cruft in NFS and 64->32 bit mapping
1801 is dealt with in posix.c
1802 Returns True if we have information regarding this lock region (and returns
1803 F_UNLCK in *ptype if the region is unlocked). False if the call failed.
1804 ****************************************************************************/
1806 bool fcntl_getlock(int fd, SMB_OFF_T *poffset, SMB_OFF_T *pcount, int *ptype, pid_t *ppid)
1808 SMB_STRUCT_FLOCK lock;
1809 int ret;
1811 DEBUG(8,("fcntl_getlock fd=%d offset=%.0f count=%.0f type=%d\n",
1812 fd,(double)*poffset,(double)*pcount,*ptype));
1814 lock.l_type = *ptype;
1815 lock.l_whence = SEEK_SET;
1816 lock.l_start = *poffset;
1817 lock.l_len = *pcount;
1818 lock.l_pid = 0;
1820 ret = sys_fcntl_ptr(fd,SMB_F_GETLK,&lock);
1822 if (ret == -1) {
1823 int sav = errno;
1824 DEBUG(3,("fcntl_getlock: lock request failed at offset %.0f count %.0f type %d (%s)\n",
1825 (double)*poffset,(double)*pcount,*ptype,strerror(errno)));
1826 errno = sav;
1827 return False;
1830 *ptype = lock.l_type;
1831 *poffset = lock.l_start;
1832 *pcount = lock.l_len;
1833 *ppid = lock.l_pid;
1835 DEBUG(3,("fcntl_getlock: fd %d is returned info %d pid %u\n",
1836 fd, (int)lock.l_type, (unsigned int)lock.l_pid));
1837 return True;
1840 #undef DBGC_CLASS
1841 #define DBGC_CLASS DBGC_ALL
1843 /*******************************************************************
1844 Is the name specified one of my netbios names.
1845 Returns true if it is equal, false otherwise.
1846 ********************************************************************/
1848 bool is_myname(const char *s)
1850 int n;
1851 bool ret = False;
1853 for (n=0; my_netbios_names(n); n++) {
1854 if (strequal(my_netbios_names(n), s)) {
1855 ret=True;
1856 break;
1859 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
1860 return(ret);
1863 /*******************************************************************
1864 Is the name specified our workgroup/domain.
1865 Returns true if it is equal, false otherwise.
1866 ********************************************************************/
1868 bool is_myworkgroup(const char *s)
1870 bool ret = False;
1872 if (strequal(s, lp_workgroup())) {
1873 ret=True;
1876 DEBUG(8, ("is_myworkgroup(\"%s\") returns %d\n", s, ret));
1877 return(ret);
1880 /*******************************************************************
1881 we distinguish between 2K and XP by the "Native Lan Manager" string
1882 WinXP => "Windows 2002 5.1"
1883 WinXP 64bit => "Windows XP 5.2"
1884 Win2k => "Windows 2000 5.0"
1885 NT4 => "Windows NT 4.0"
1886 Win9x => "Windows 4.0"
1887 Windows 2003 doesn't set the native lan manager string but
1888 they do set the domain to "Windows 2003 5.2" (probably a bug).
1889 ********************************************************************/
1891 void ra_lanman_string( const char *native_lanman )
1893 if ( strcmp( native_lanman, "Windows 2002 5.1" ) == 0 )
1894 set_remote_arch( RA_WINXP );
1895 else if ( strcmp( native_lanman, "Windows XP 5.2" ) == 0 )
1896 set_remote_arch( RA_WINXP64 );
1897 else if ( strcmp( native_lanman, "Windows Server 2003 5.2" ) == 0 )
1898 set_remote_arch( RA_WIN2K3 );
1901 static const char *remote_arch_str;
1903 const char *get_remote_arch_str(void)
1905 if (!remote_arch_str) {
1906 return "UNKNOWN";
1908 return remote_arch_str;
1911 /*******************************************************************
1912 Set the horrid remote_arch string based on an enum.
1913 ********************************************************************/
1915 void set_remote_arch(enum remote_arch_types type)
1917 ra_type = type;
1918 switch( type ) {
1919 case RA_WFWG:
1920 remote_arch_str = "WfWg";
1921 break;
1922 case RA_OS2:
1923 remote_arch_str = "OS2";
1924 break;
1925 case RA_WIN95:
1926 remote_arch_str = "Win95";
1927 break;
1928 case RA_WINNT:
1929 remote_arch_str = "WinNT";
1930 break;
1931 case RA_WIN2K:
1932 remote_arch_str = "Win2K";
1933 break;
1934 case RA_WINXP:
1935 remote_arch_str = "WinXP";
1936 break;
1937 case RA_WINXP64:
1938 remote_arch_str = "WinXP64";
1939 break;
1940 case RA_WIN2K3:
1941 remote_arch_str = "Win2K3";
1942 break;
1943 case RA_VISTA:
1944 remote_arch_str = "Vista";
1945 break;
1946 case RA_SAMBA:
1947 remote_arch_str = "Samba";
1948 break;
1949 case RA_CIFSFS:
1950 remote_arch_str = "CIFSFS";
1951 break;
1952 default:
1953 ra_type = RA_UNKNOWN;
1954 remote_arch_str = "UNKNOWN";
1955 break;
1958 DEBUG(10,("set_remote_arch: Client arch is \'%s\'\n",
1959 remote_arch_str));
1962 /*******************************************************************
1963 Get the remote_arch type.
1964 ********************************************************************/
1966 enum remote_arch_types get_remote_arch(void)
1968 return ra_type;
1971 const char *tab_depth(int level, int depth)
1973 if( CHECK_DEBUGLVL(level) ) {
1974 dbgtext("%*s", depth*4, "");
1976 return "";
1979 /*****************************************************************************
1980 Provide a checksum on a string
1982 Input: s - the null-terminated character string for which the checksum
1983 will be calculated.
1985 Output: The checksum value calculated for s.
1986 *****************************************************************************/
1988 int str_checksum(const char *s)
1990 int res = 0;
1991 int c;
1992 int i=0;
1994 while(*s) {
1995 c = *s;
1996 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
1997 s++;
1998 i++;
2000 return(res);
2003 /*****************************************************************
2004 Zero a memory area then free it. Used to catch bugs faster.
2005 *****************************************************************/
2007 void zero_free(void *p, size_t size)
2009 memset(p, 0, size);
2010 SAFE_FREE(p);
2013 /*****************************************************************
2014 Set our open file limit to a requested max and return the limit.
2015 *****************************************************************/
2017 int set_maxfiles(int requested_max)
2019 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
2020 struct rlimit rlp;
2021 int saved_current_limit;
2023 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2024 DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
2025 strerror(errno) ));
2026 /* just guess... */
2027 return requested_max;
2031 * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
2032 * account for the extra fd we need
2033 * as well as the log files and standard
2034 * handles etc. Save the limit we want to set in case
2035 * we are running on an OS that doesn't support this limit (AIX)
2036 * which always returns RLIM_INFINITY for rlp.rlim_max.
2039 /* Try raising the hard (max) limit to the requested amount. */
2041 #if defined(RLIM_INFINITY)
2042 if (rlp.rlim_max != RLIM_INFINITY) {
2043 int orig_max = rlp.rlim_max;
2045 if ( rlp.rlim_max < requested_max )
2046 rlp.rlim_max = requested_max;
2048 /* This failing is not an error - many systems (Linux) don't
2049 support our default request of 10,000 open files. JRA. */
2051 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2052 DEBUG(3,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d max files failed with error %s\n",
2053 (int)rlp.rlim_max, strerror(errno) ));
2055 /* Set failed - restore original value from get. */
2056 rlp.rlim_max = orig_max;
2059 #endif
2061 /* Now try setting the soft (current) limit. */
2063 saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
2065 if(setrlimit(RLIMIT_NOFILE, &rlp)) {
2066 DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
2067 (int)rlp.rlim_cur, strerror(errno) ));
2068 /* just guess... */
2069 return saved_current_limit;
2072 if(getrlimit(RLIMIT_NOFILE, &rlp)) {
2073 DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
2074 strerror(errno) ));
2075 /* just guess... */
2076 return saved_current_limit;
2079 #if defined(RLIM_INFINITY)
2080 if(rlp.rlim_cur == RLIM_INFINITY)
2081 return saved_current_limit;
2082 #endif
2084 if((int)rlp.rlim_cur > saved_current_limit)
2085 return saved_current_limit;
2087 return rlp.rlim_cur;
2088 #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
2090 * No way to know - just guess...
2092 return requested_max;
2093 #endif
2096 /*****************************************************************
2097 malloc that aborts with smb_panic on fail or zero size.
2098 *****************************************************************/
2100 void *smb_xmalloc_array(size_t size, unsigned int count)
2102 void *p;
2103 if (size == 0) {
2104 smb_panic("smb_xmalloc_array: called with zero size");
2106 if (count >= MAX_ALLOC_SIZE/size) {
2107 smb_panic("smb_xmalloc_array: alloc size too large");
2109 if ((p = SMB_MALLOC(size*count)) == NULL) {
2110 DEBUG(0, ("smb_xmalloc_array failed to allocate %lu * %lu bytes\n",
2111 (unsigned long)size, (unsigned long)count));
2112 smb_panic("smb_xmalloc_array: malloc failed");
2114 return p;
2118 vasprintf that aborts on malloc fail
2121 int smb_xvasprintf(char **ptr, const char *format, va_list ap)
2123 int n;
2124 va_list ap2;
2126 va_copy(ap2, ap);
2128 n = vasprintf(ptr, format, ap2);
2129 va_end(ap2);
2130 if (n == -1 || ! *ptr) {
2131 smb_panic("smb_xvasprintf: out of memory");
2133 return n;
2136 /*****************************************************************
2137 Get local hostname and cache result.
2138 *****************************************************************/
2140 char *myhostname(void)
2142 static char *ret;
2143 if (ret == NULL) {
2144 /* This is cached forever so
2145 * use talloc_autofree_context() ctx. */
2146 ret = get_myname(talloc_autofree_context());
2148 return ret;
2152 * @brief Returns an absolute path to a file concatenating the provided
2153 * @a rootpath and @a basename
2155 * @param name Filename, relative to @a rootpath
2157 * @retval Pointer to a string containing the full path.
2160 static char *xx_path(const char *name, const char *rootpath)
2162 char *fname = NULL;
2164 fname = talloc_strdup(talloc_tos(), rootpath);
2165 if (!fname) {
2166 return NULL;
2168 trim_string(fname,"","/");
2170 if (!directory_exist(fname)) {
2171 if (!mkdir(fname,0755))
2172 DEBUG(1, ("Unable to create directory %s for file %s. "
2173 "Error was %s\n", fname, name, strerror(errno)));
2176 return talloc_asprintf(talloc_tos(),
2177 "%s/%s",
2178 fname,
2179 name);
2183 * @brief Returns an absolute path to a file in the Samba lock directory.
2185 * @param name File to find, relative to LOCKDIR.
2187 * @retval Pointer to a talloc'ed string containing the full path.
2190 char *lock_path(const char *name)
2192 return xx_path(name, lp_lockdir());
2196 * @brief Returns an absolute path to a file in the Samba pid directory.
2198 * @param name File to find, relative to PIDDIR.
2200 * @retval Pointer to a talloc'ed string containing the full path.
2203 char *pid_path(const char *name)
2205 return xx_path(name, lp_piddir());
2209 * @brief Returns an absolute path to a file in the Samba lib directory.
2211 * @param name File to find, relative to LIBDIR.
2213 * @retval Pointer to a string containing the full path.
2216 char *lib_path(const char *name)
2218 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_LIBDIR(), name);
2222 * @brief Returns an absolute path to a file in the Samba modules directory.
2224 * @param name File to find, relative to MODULESDIR.
2226 * @retval Pointer to a string containing the full path.
2229 char *modules_path(const char *name)
2231 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_MODULESDIR(), name);
2235 * @brief Returns an absolute path to a file in the Samba data directory.
2237 * @param name File to find, relative to CODEPAGEDIR.
2239 * @retval Pointer to a talloc'ed string containing the full path.
2242 char *data_path(const char *name)
2244 return talloc_asprintf(talloc_tos(), "%s/%s", get_dyn_CODEPAGEDIR(), name);
2248 * @brief Returns an absolute path to a file in the Samba state directory.
2250 * @param name File to find, relative to STATEDIR.
2252 * @retval Pointer to a talloc'ed string containing the full path.
2255 char *state_path(const char *name)
2257 return xx_path(name, lp_statedir());
2261 * @brief Returns an absolute path to a file in the Samba cache directory.
2263 * @param name File to find, relative to CACHEDIR.
2265 * @retval Pointer to a talloc'ed string containing the full path.
2268 char *cache_path(const char *name)
2270 return xx_path(name, lp_cachedir());
2274 * @brief Returns the platform specific shared library extension.
2276 * @retval Pointer to a const char * containing the extension.
2279 const char *shlib_ext(void)
2281 return get_dyn_SHLIBEXT();
2284 /*******************************************************************
2285 Given a filename - get its directory name
2286 ********************************************************************/
2288 bool parent_dirname(TALLOC_CTX *mem_ctx, const char *dir, char **parent,
2289 const char **name)
2291 char *p;
2292 ptrdiff_t len;
2294 p = strrchr_m(dir, '/'); /* Find final '/', if any */
2296 if (p == NULL) {
2297 if (!(*parent = talloc_strdup(mem_ctx, "."))) {
2298 return False;
2300 if (name) {
2301 *name = dir;
2303 return True;
2306 len = p-dir;
2308 if (!(*parent = (char *)TALLOC_MEMDUP(mem_ctx, dir, len+1))) {
2309 return False;
2311 (*parent)[len] = '\0';
2313 if (name) {
2314 *name = p+1;
2316 return True;
2319 /*******************************************************************
2320 Determine if a pattern contains any Microsoft wildcard characters.
2321 *******************************************************************/
2323 bool ms_has_wild(const char *s)
2325 char c;
2327 if (lp_posix_pathnames()) {
2328 /* With posix pathnames no characters are wild. */
2329 return False;
2332 while ((c = *s++)) {
2333 switch (c) {
2334 case '*':
2335 case '?':
2336 case '<':
2337 case '>':
2338 case '"':
2339 return True;
2342 return False;
2345 bool ms_has_wild_w(const smb_ucs2_t *s)
2347 smb_ucs2_t c;
2348 if (!s) return False;
2349 while ((c = *s++)) {
2350 switch (c) {
2351 case UCS2_CHAR('*'):
2352 case UCS2_CHAR('?'):
2353 case UCS2_CHAR('<'):
2354 case UCS2_CHAR('>'):
2355 case UCS2_CHAR('"'):
2356 return True;
2359 return False;
2362 /*******************************************************************
2363 A wrapper that handles case sensitivity and the special handling
2364 of the ".." name.
2365 *******************************************************************/
2367 bool mask_match(const char *string, const char *pattern, bool is_case_sensitive)
2369 if (ISDOTDOT(string))
2370 string = ".";
2371 if (ISDOT(pattern))
2372 return False;
2374 return ms_fnmatch(pattern, string, Protocol <= PROTOCOL_LANMAN2, is_case_sensitive) == 0;
2377 /*******************************************************************
2378 A wrapper that handles case sensitivity and the special handling
2379 of the ".." name. Varient that is only called by old search code which requires
2380 pattern translation.
2381 *******************************************************************/
2383 bool mask_match_search(const char *string, const char *pattern, bool is_case_sensitive)
2385 if (ISDOTDOT(string))
2386 string = ".";
2387 if (ISDOT(pattern))
2388 return False;
2390 return ms_fnmatch(pattern, string, True, is_case_sensitive) == 0;
2393 /*******************************************************************
2394 A wrapper that handles a list of patters and calls mask_match()
2395 on each. Returns True if any of the patterns match.
2396 *******************************************************************/
2398 bool mask_match_list(const char *string, char **list, int listLen, bool is_case_sensitive)
2400 while (listLen-- > 0) {
2401 if (mask_match(string, *list++, is_case_sensitive))
2402 return True;
2404 return False;
2407 /*********************************************************
2408 Recursive routine that is called by unix_wild_match.
2409 *********************************************************/
2411 static bool unix_do_match(const char *regexp, const char *str)
2413 const char *p;
2415 for( p = regexp; *p && *str; ) {
2417 switch(*p) {
2418 case '?':
2419 str++;
2420 p++;
2421 break;
2423 case '*':
2426 * Look for a character matching
2427 * the one after the '*'.
2429 p++;
2430 if(!*p)
2431 return true; /* Automatic match */
2432 while(*str) {
2434 while(*str && (*p != *str))
2435 str++;
2438 * Patch from weidel@multichart.de. In the case of the regexp
2439 * '*XX*' we want to ensure there are at least 2 'X' characters
2440 * in the string after the '*' for a match to be made.
2444 int matchcount=0;
2447 * Eat all the characters that match, but count how many there were.
2450 while(*str && (*p == *str)) {
2451 str++;
2452 matchcount++;
2456 * Now check that if the regexp had n identical characters that
2457 * matchcount had at least that many matches.
2460 while ( *(p+1) && (*(p+1) == *p)) {
2461 p++;
2462 matchcount--;
2465 if ( matchcount <= 0 )
2466 return false;
2469 str--; /* We've eaten the match char after the '*' */
2471 if(unix_do_match(p, str))
2472 return true;
2474 if(!*str)
2475 return false;
2476 else
2477 str++;
2479 return false;
2481 default:
2482 if(*str != *p)
2483 return false;
2484 str++;
2485 p++;
2486 break;
2490 if(!*p && !*str)
2491 return true;
2493 if (!*p && str[0] == '.' && str[1] == 0)
2494 return true;
2496 if (!*str && *p == '?') {
2497 while (*p == '?')
2498 p++;
2499 return(!*p);
2502 if(!*str && (*p == '*' && p[1] == '\0'))
2503 return true;
2505 return false;
2508 /*******************************************************************
2509 Simple case insensitive interface to a UNIX wildcard matcher.
2510 Returns True if match, False if not.
2511 *******************************************************************/
2513 bool unix_wild_match(const char *pattern, const char *string)
2515 TALLOC_CTX *ctx = talloc_stackframe();
2516 char *p2;
2517 char *s2;
2518 char *p;
2519 bool ret = false;
2521 p2 = talloc_strdup(ctx,pattern);
2522 s2 = talloc_strdup(ctx,string);
2523 if (!p2 || !s2) {
2524 TALLOC_FREE(ctx);
2525 return false;
2527 strlower_m(p2);
2528 strlower_m(s2);
2530 /* Remove any *? and ** from the pattern as they are meaningless */
2531 for(p = p2; *p; p++) {
2532 while( *p == '*' && (p[1] == '?' ||p[1] == '*')) {
2533 memmove(&p[1], &p[2], strlen(&p[2])+1);
2537 if (strequal(p2,"*")) {
2538 TALLOC_FREE(ctx);
2539 return true;
2542 ret = unix_do_match(p2, s2);
2543 TALLOC_FREE(ctx);
2544 return ret;
2547 /**********************************************************************
2548 Converts a name to a fully qualified domain name.
2549 Returns true if lookup succeeded, false if not (then fqdn is set to name)
2550 Note we deliberately use gethostbyname here, not getaddrinfo as we want
2551 to examine the h_aliases and I don't know how to do that with getaddrinfo.
2552 ***********************************************************************/
2554 bool name_to_fqdn(fstring fqdn, const char *name)
2556 char *full = NULL;
2557 struct hostent *hp = gethostbyname(name);
2559 if (!hp || !hp->h_name || !*hp->h_name) {
2560 DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
2561 fstrcpy(fqdn, name);
2562 return false;
2565 /* Find out if the fqdn is returned as an alias
2566 * to cope with /etc/hosts files where the first
2567 * name is not the fqdn but the short name */
2568 if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
2569 int i;
2570 for (i = 0; hp->h_aliases[i]; i++) {
2571 if (strchr_m(hp->h_aliases[i], '.')) {
2572 full = hp->h_aliases[i];
2573 break;
2577 if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
2578 DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
2579 DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
2580 DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
2581 DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
2582 full = hp->h_name;
2584 if (!full) {
2585 full = hp->h_name;
2588 DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
2589 fstrcpy(fqdn, full);
2590 return true;
2593 /**********************************************************************
2594 Append a DATA_BLOB to a talloc'ed object
2595 ***********************************************************************/
2597 void *talloc_append_blob(TALLOC_CTX *mem_ctx, void *buf, DATA_BLOB blob)
2599 size_t old_size = 0;
2600 char *result;
2602 if (blob.length == 0) {
2603 return buf;
2606 if (buf != NULL) {
2607 old_size = talloc_get_size(buf);
2610 result = (char *)TALLOC_REALLOC(mem_ctx, buf, old_size + blob.length);
2611 if (result == NULL) {
2612 return NULL;
2615 memcpy(result + old_size, blob.data, blob.length);
2616 return result;
2619 uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
2621 switch (share_access & ~FILE_SHARE_DELETE) {
2622 case FILE_SHARE_NONE:
2623 return DENY_ALL;
2624 case FILE_SHARE_READ:
2625 return DENY_WRITE;
2626 case FILE_SHARE_WRITE:
2627 return DENY_READ;
2628 case FILE_SHARE_READ|FILE_SHARE_WRITE:
2629 return DENY_NONE;
2631 if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
2632 return DENY_DOS;
2633 } else if (private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_FCB) {
2634 return DENY_FCB;
2637 return (uint32)-1;
2640 pid_t procid_to_pid(const struct server_id *proc)
2642 return proc->pid;
2645 static uint32 my_vnn = NONCLUSTER_VNN;
2647 void set_my_vnn(uint32 vnn)
2649 DEBUG(10, ("vnn pid %d = %u\n", (int)sys_getpid(), (unsigned int)vnn));
2650 my_vnn = vnn;
2653 uint32 get_my_vnn(void)
2655 return my_vnn;
2658 struct server_id pid_to_procid(pid_t pid)
2660 struct server_id result;
2661 result.pid = pid;
2662 #ifdef CLUSTER_SUPPORT
2663 result.vnn = my_vnn;
2664 #endif
2665 return result;
2668 struct server_id procid_self(void)
2670 return pid_to_procid(sys_getpid());
2673 struct server_id server_id_self(void)
2675 return procid_self();
2678 bool procid_equal(const struct server_id *p1, const struct server_id *p2)
2680 if (p1->pid != p2->pid)
2681 return False;
2682 #ifdef CLUSTER_SUPPORT
2683 if (p1->vnn != p2->vnn)
2684 return False;
2685 #endif
2686 return True;
2689 bool cluster_id_equal(const struct server_id *id1,
2690 const struct server_id *id2)
2692 return procid_equal(id1, id2);
2695 bool procid_is_me(const struct server_id *pid)
2697 if (pid->pid != sys_getpid())
2698 return False;
2699 #ifdef CLUSTER_SUPPORT
2700 if (pid->vnn != my_vnn)
2701 return False;
2702 #endif
2703 return True;
2706 struct server_id interpret_pid(const char *pid_string)
2708 struct server_id result;
2709 int pid;
2710 #ifdef CLUSTER_SUPPORT
2711 unsigned int vnn;
2712 if (sscanf(pid_string, "%u:%d", &vnn, &pid) == 2) {
2713 result.vnn = vnn;
2714 result.pid = pid;
2716 else if (sscanf(pid_string, "%d", &pid) == 1) {
2717 result.vnn = get_my_vnn();
2718 result.pid = pid;
2720 else {
2721 result.vnn = NONCLUSTER_VNN;
2722 result.pid = -1;
2724 #else
2725 if (sscanf(pid_string, "%d", &pid) != 1) {
2726 result.pid = -1;
2727 } else {
2728 result.pid = pid;
2730 #endif
2731 /* Assigning to result.pid may have overflowed
2732 Map negative pid to -1: i.e. error */
2733 if (result.pid < 0) {
2734 result.pid = -1;
2736 return result;
2739 char *procid_str(TALLOC_CTX *mem_ctx, const struct server_id *pid)
2741 #ifdef CLUSTER_SUPPORT
2742 if (pid->vnn == NONCLUSTER_VNN) {
2743 return talloc_asprintf(mem_ctx,
2744 "%d",
2745 (int)pid->pid);
2747 else {
2748 return talloc_asprintf(mem_ctx,
2749 "%u:%d",
2750 (unsigned)pid->vnn,
2751 (int)pid->pid);
2753 #else
2754 return talloc_asprintf(mem_ctx,
2755 "%d",
2756 (int)pid->pid);
2757 #endif
2760 char *procid_str_static(const struct server_id *pid)
2762 return procid_str(talloc_tos(), pid);
2765 bool procid_valid(const struct server_id *pid)
2767 return (pid->pid != -1);
2770 bool procid_is_local(const struct server_id *pid)
2772 #ifdef CLUSTER_SUPPORT
2773 return pid->vnn == my_vnn;
2774 #else
2775 return True;
2776 #endif
2779 int this_is_smp(void)
2781 #if defined(HAVE_SYSCONF)
2783 #if defined(SYSCONF_SC_NPROC_ONLN)
2784 return (sysconf(_SC_NPROC_ONLN) > 1) ? 1 : 0;
2785 #elif defined(SYSCONF_SC_NPROCESSORS_ONLN)
2786 return (sysconf(_SC_NPROCESSORS_ONLN) > 1) ? 1 : 0;
2787 #else
2788 return 0;
2789 #endif
2791 #else
2792 return 0;
2793 #endif
2796 /****************************************************************
2797 Check if offset/length fit into bufsize. Should probably be
2798 merged with is_offset_safe, but this would require a rewrite
2799 of lanman.c. Later :-)
2800 ****************************************************************/
2802 bool trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length)
2804 if ((offset + length < offset) || (offset + length < length)) {
2805 /* wrap */
2806 return true;
2808 if ((offset > bufsize) || (offset + length > bufsize)) {
2809 /* overflow */
2810 return true;
2812 return false;
2815 /****************************************************************
2816 Check if an offset into a buffer is safe.
2817 If this returns True it's safe to indirect into the byte at
2818 pointer ptr+off.
2819 ****************************************************************/
2821 bool is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2823 const char *end_base = buf_base + buf_len;
2824 char *end_ptr = ptr + off;
2826 if (!buf_base || !ptr) {
2827 return False;
2830 if (end_base < buf_base || end_ptr < ptr) {
2831 return False; /* wrap. */
2834 if (end_ptr < end_base) {
2835 return True;
2837 return False;
2840 /****************************************************************
2841 Return a safe pointer into a buffer, or NULL.
2842 ****************************************************************/
2844 char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2846 return is_offset_safe(buf_base, buf_len, ptr, off) ?
2847 ptr + off : NULL;
2850 /****************************************************************
2851 Return a safe pointer into a string within a buffer, or NULL.
2852 ****************************************************************/
2854 char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
2856 if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
2857 return NULL;
2859 /* Check if a valid string exists at this offset. */
2860 if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
2861 return NULL;
2863 return ptr + off;
2866 /****************************************************************
2867 Return an SVAL at a pointer, or failval if beyond the end.
2868 ****************************************************************/
2870 int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2873 * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
2874 * NOT ptr[2].
2876 if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
2877 return failval;
2879 return SVAL(ptr,off);
2882 /****************************************************************
2883 Return an IVAL at a pointer, or failval if beyond the end.
2884 ****************************************************************/
2886 int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
2889 * Note we use off+3 here, not off+4 as IVAL accesses
2890 * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
2892 if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
2893 return failval;
2895 return IVAL(ptr,off);
2898 /****************************************************************
2899 Split DOM\user into DOM and user. Do not mix with winbind variants of that
2900 call (they take care of winbind separator and other winbind specific settings).
2901 ****************************************************************/
2903 void split_domain_user(TALLOC_CTX *mem_ctx,
2904 const char *full_name,
2905 char **domain,
2906 char **user)
2908 const char *p = NULL;
2910 p = strchr_m(full_name, '\\');
2912 if (p != NULL) {
2913 *domain = talloc_strndup(mem_ctx, full_name,
2914 PTR_DIFF(p, full_name));
2915 *user = talloc_strdup(mem_ctx, p+1);
2916 } else {
2917 *domain = talloc_strdup(mem_ctx, "");
2918 *user = talloc_strdup(mem_ctx, full_name);
2922 #if 0
2924 Disable these now we have checked all code paths and ensured
2925 NULL returns on zero request. JRA.
2927 /****************************************************************
2928 talloc wrapper functions that guarentee a null pointer return
2929 if size == 0.
2930 ****************************************************************/
2932 #ifndef MAX_TALLOC_SIZE
2933 #define MAX_TALLOC_SIZE 0x10000000
2934 #endif
2937 * talloc and zero memory.
2938 * - returns NULL if size is zero.
2941 void *_talloc_zero_zeronull(const void *ctx, size_t size, const char *name)
2943 void *p;
2945 if (size == 0) {
2946 return NULL;
2949 p = talloc_named_const(ctx, size, name);
2951 if (p) {
2952 memset(p, '\0', size);
2955 return p;
2959 * memdup with a talloc.
2960 * - returns NULL if size is zero.
2963 void *_talloc_memdup_zeronull(const void *t, const void *p, size_t size, const char *name)
2965 void *newp;
2967 if (size == 0) {
2968 return NULL;
2971 newp = talloc_named_const(t, size, name);
2972 if (newp) {
2973 memcpy(newp, p, size);
2976 return newp;
2980 * alloc an array, checking for integer overflow in the array size.
2981 * - returns NULL if count or el_size are zero.
2984 void *_talloc_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
2986 if (count >= MAX_TALLOC_SIZE/el_size) {
2987 return NULL;
2990 if (el_size == 0 || count == 0) {
2991 return NULL;
2994 return talloc_named_const(ctx, el_size * count, name);
2998 * alloc an zero array, checking for integer overflow in the array size
2999 * - returns NULL if count or el_size are zero.
3002 void *_talloc_zero_array_zeronull(const void *ctx, size_t el_size, unsigned count, const char *name)
3004 if (count >= MAX_TALLOC_SIZE/el_size) {
3005 return NULL;
3008 if (el_size == 0 || count == 0) {
3009 return NULL;
3012 return _talloc_zero(ctx, el_size * count, name);
3016 * Talloc wrapper that returns NULL if size == 0.
3018 void *talloc_zeronull(const void *context, size_t size, const char *name)
3020 if (size == 0) {
3021 return NULL;
3023 return talloc_named_const(context, size, name);
3025 #endif
3027 bool is_valid_policy_hnd(const struct policy_handle *hnd)
3029 struct policy_handle tmp;
3030 ZERO_STRUCT(tmp);
3031 return (memcmp(&tmp, hnd, sizeof(tmp)) != 0);
3034 bool policy_hnd_equal(const struct policy_handle *hnd1,
3035 const struct policy_handle *hnd2)
3037 if (!hnd1 || !hnd2) {
3038 return false;
3041 return (memcmp(hnd1, hnd2, sizeof(*hnd1)) == 0);
3044 /****************************************************************
3045 strip off leading '\\' from a hostname
3046 ****************************************************************/
3048 const char *strip_hostname(const char *s)
3050 if (!s) {
3051 return NULL;
3054 if (strlen_m(s) < 3) {
3055 return s;
3058 if (s[0] == '\\') s++;
3059 if (s[0] == '\\') s++;
3061 return s;
3064 bool tevent_req_poll_ntstatus(struct tevent_req *req,
3065 struct tevent_context *ev,
3066 NTSTATUS *status)
3068 bool ret = tevent_req_poll(req, ev);
3069 if (!ret) {
3070 *status = map_nt_error_from_unix(errno);
3072 return ret;