2 Unix SMB/Netbios implementation.
4 Samba utility functions
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
25 #ifdef WITH_NISPLUS_HOME
26 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
34 #undef Realloc /* SSLeay defines this and samba has a function of this name */
41 extern int DEBUGLEVEL;
45 int Protocol = PROTOCOL_COREPLUS;
47 /* a default finfo structure to ensure all fields are sensible */
48 file_info def_finfo = {-1,0,0,0,0,0,0,""};
50 /* the client file descriptor */
53 /* the last IP received from */
54 struct in_addr lastip;
56 /* the last port received from */
59 /* this is used by the chaining code */
65 case handling on filenames
67 int case_default = CASE_LOWER;
69 /* the following control case operations - they are put here so the
70 client can link easily */
73 BOOL use_mangled_map = False;
74 BOOL short_case_preserve;
77 fstring remote_machine="";
78 fstring local_machine="";
79 fstring remote_arch="UNKNOWN";
80 static enum remote_arch_types ra_type = RA_UNKNOWN;
81 fstring remote_proto="UNKNOWN";
82 pstring myhostname="";
83 pstring user_socket_options="";
85 pstring sesssetup_user="";
86 pstring samlogon_user="";
88 BOOL sam_logon_in_ssb = False;
90 pstring global_myname = "";
91 fstring global_myworkgroup = "";
92 char **my_netbios_names;
94 int smb_read_error = 0;
96 static char *filename_dos(char *path,char *buf);
100 /****************************************************************************
101 find a suitable temporary directory. The result should be copied immediately
102 as it may be overwritten by a subsequent call
103 ****************************************************************************/
107 if ((p = getenv("TMPDIR"))) {
115 /****************************************************************************
116 determine if a file descriptor is in fact a socket
117 ****************************************************************************/
118 BOOL is_a_socket(int fd)
122 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
126 static char *last_ptr=NULL;
128 /****************************************************************************
129 Get the next token from a string, return False if none found
130 handles double-quotes.
131 Based on a routine by GJC@VILLAGE.COM.
132 Extensively modified by Andrew.Tridgell@anu.edu.au
133 ****************************************************************************/
134 BOOL next_token(char **ptr,char *buff,char *sep, int bufsize)
140 if (!ptr) ptr = &last_ptr;
141 if (!ptr) return(False);
145 /* default to simple separators */
146 if (!sep) sep = " \t\n\r";
148 /* find the first non sep char */
149 while(*s && strchr(sep,*s)) s++;
152 if (! *s) return(False);
154 /* copy over the token */
155 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
165 *ptr = (*s) ? s+1 : s;
172 /****************************************************************************
173 Convert list of tokens to array; dependent on above routine.
174 Uses last_ptr from above - bit of a hack.
175 ****************************************************************************/
176 char **toktocliplist(int *ctok, char *sep)
182 if (!sep) sep = " \t\n\r";
184 while(*s && strchr(sep,*s)) s++;
187 if (!*s) return(NULL);
191 while(*s && (!strchr(sep,*s))) s++;
192 while(*s && strchr(sep,*s)) *s++=0;
198 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
209 /****************************************************************************
210 prompte a dptr (to make it recently used)
211 ****************************************************************************/
212 static void array_promote(char *array,int elsize,int element)
218 p = (char *)malloc(elsize);
222 DEBUG(5,("Ahh! Can't malloc\n"));
225 memcpy(p,array + element * elsize, elsize);
226 memmove(array + elsize,array,elsize*element);
227 memcpy(array,p,elsize);
231 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
240 } socket_options[] = {
241 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
242 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
243 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
245 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
247 #ifdef IPTOS_LOWDELAY
248 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
250 #ifdef IPTOS_THROUGHPUT
251 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
254 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
257 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
260 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
263 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
266 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
269 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
275 /****************************************************************************
276 set user socket options
277 ****************************************************************************/
278 void set_socket_options(int fd, char *options)
282 while (next_token(&options,tok," \t,", sizeof(tok)))
287 BOOL got_value = False;
289 if ((p = strchr(tok,'=')))
296 for (i=0;socket_options[i].name;i++)
297 if (strequal(socket_options[i].name,tok))
300 if (!socket_options[i].name)
302 DEBUG(0,("Unknown socket option %s\n",tok));
306 switch (socket_options[i].opttype)
310 ret = setsockopt(fd,socket_options[i].level,
311 socket_options[i].option,(char *)&value,sizeof(int));
316 DEBUG(0,("syntax error - %s does not take a value\n",tok));
319 int on = socket_options[i].value;
320 ret = setsockopt(fd,socket_options[i].level,
321 socket_options[i].option,(char *)&on,sizeof(int));
327 DEBUG(0,("Failed to set socket option %s\n",tok));
333 /****************************************************************************
334 close the socket communication
335 ****************************************************************************/
336 void close_sockets(void )
339 sslutil_disconnect(Client);
340 #endif /* WITH_SSL */
346 /****************************************************************************
347 determine whether we are in the specified group
348 ****************************************************************************/
349 BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
353 if (group == current_gid) return(True);
355 for (i=0;i<ngroups;i++)
356 if (group == groups[i])
362 /****************************************************************************
363 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
364 ****************************************************************************/
365 char *StrCpy(char *dest,char *src)
369 /* I don't want to get lazy with these ... */
370 SMB_ASSERT(dest && src);
372 if (!dest) return(NULL);
377 while ((*d++ = *src++)) ;
381 /****************************************************************************
382 line strncpy but always null terminates. Make sure there is room!
383 ****************************************************************************/
384 char *StrnCpy(char *dest,char *src,int n)
387 if (!dest) return(NULL);
392 while (n-- && (*d++ = *src++)) ;
398 /*******************************************************************
399 copy an IP address from one buffer to another
400 ********************************************************************/
401 void putip(void *dest,void *src)
407 #define TRUNCATE_NETBIOS_NAME 1
409 /*******************************************************************
410 convert, possibly using a stupid microsoft-ism which has destroyed
411 the transport independence of netbios (for CIFS vendors that usually
412 use the Win95-type methods, not for NT to NT communication, which uses
413 DCE/RPC and therefore full-length unicode strings...) a dns name into
416 the netbios name (NOT necessarily null-terminated) is truncated to 15
419 ******************************************************************/
420 char *dns_to_netbios_name(char *dns_name)
422 static char netbios_name[16];
424 StrnCpy(netbios_name, dns_name, 15);
425 netbios_name[15] = 0;
427 #ifdef TRUNCATE_NETBIOS_NAME
428 /* ok. this is because of a stupid microsoft-ism. if the called host
429 name contains a '.', microsoft clients expect you to truncate the
430 netbios name up to and including the '.' this even applies, by
431 mistake, to workgroup (domain) names, which is _really_ daft.
433 for (i = 15; i >= 0; i--)
435 if (netbios_name[i] == '.')
441 #endif /* TRUNCATE_NETBIOS_NAME */
447 /****************************************************************************
448 interpret the weird netbios "name". Return the name type
449 ****************************************************************************/
450 static int name_interpret(char *in,char *out)
453 int len = (*in++) / 2;
457 if (len > 30 || len<1) return(0);
461 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
465 *out = ((in[0]-'A')<<4) + (in[1]-'A');
473 /* Handle any scope names */
476 *out++ = '.'; /* Scope names are separated by periods */
477 len = *(unsigned char *)in++;
478 StrnCpy(out, in, len);
487 /****************************************************************************
488 mangle a name into netbios format
490 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
491 ****************************************************************************/
492 int name_mangle( char *In, char *Out, char name_type )
500 /* Safely copy the input string, In, into buf[]. */
501 (void)memset( buf, 0, 20 );
505 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
507 /* Place the length of the first field into the output buffer. */
511 /* Now convert the name to the rfc1001/1002 format. */
512 for( i = 0; i < 16; i++ )
514 c = toupper( buf[i] );
515 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
516 p[(i*2)+1] = (c & 0x000F) + 'A';
521 /* Add the scope string. */
522 for( i = 0, len = 0; NULL != scope; i++, len++ )
530 return( name_len(Out) );
542 return( name_len(Out) );
545 /*******************************************************************
546 check if a file exists
547 ********************************************************************/
548 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
551 if (!sbuf) sbuf = &st;
553 if (dos_stat(fname,sbuf) != 0)
556 return(S_ISREG(sbuf->st_mode));
559 /*******************************************************************
560 check a files mod time
561 ********************************************************************/
562 time_t file_modtime(char *fname)
566 if (dos_stat(fname,&st) != 0)
572 /*******************************************************************
573 check if a directory exists
574 ********************************************************************/
575 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
582 if (dos_stat(dname,st) != 0)
585 ret = S_ISDIR(st->st_mode);
591 /*******************************************************************
592 returns the size in bytes of the named file
593 ********************************************************************/
594 SMB_OFF_T file_size(char *file_name)
598 dos_stat(file_name,&buf);
602 /*******************************************************************
603 return a string representing an attribute for a file
604 ********************************************************************/
605 char *attrib_string(int mode)
607 static fstring attrstr;
611 if (mode & aVOLID) fstrcat(attrstr,"V");
612 if (mode & aDIR) fstrcat(attrstr,"D");
613 if (mode & aARCH) fstrcat(attrstr,"A");
614 if (mode & aHIDDEN) fstrcat(attrstr,"H");
615 if (mode & aSYSTEM) fstrcat(attrstr,"S");
616 if (mode & aRONLY) fstrcat(attrstr,"R");
622 /*******************************************************************
623 case insensitive string compararison
624 ********************************************************************/
625 int StrCaseCmp(char *s, char *t)
627 /* compare until we run out of string, either t or s, or find a difference */
628 /* We *must* use toupper rather than tolower here due to the
629 asynchronous upper to lower mapping.
631 #if !defined(KANJI_WIN95_COMPATIBILITY)
633 * For completeness we should put in equivalent code for code pages
634 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
635 * doubt anyone wants Samba to behave differently from Win95 and WinNT
636 * here. They both treat full width ascii characters as case senstive
637 * filenames (ie. they don't do the work we do here).
641 if(lp_client_code_page() == KANJI_CODEPAGE)
643 /* Win95 treats full width ascii characters as case sensitive. */
648 return toupper (*s) - toupper (*t);
649 else if (is_sj_alph (*s) && is_sj_alph (*t))
651 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
657 else if (is_shift_jis (*s) && is_shift_jis (*t))
659 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
662 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
668 else if (is_shift_jis (*s))
670 else if (is_shift_jis (*t))
674 diff = toupper (*s) - toupper (*t);
683 #endif /* KANJI_WIN95_COMPATIBILITY */
685 while (*s && *t && toupper(*s) == toupper(*t))
691 return(toupper(*s) - toupper(*t));
695 /*******************************************************************
696 case insensitive string compararison, length limited
697 ********************************************************************/
698 int StrnCaseCmp(char *s, char *t, int n)
700 /* compare until we run out of string, either t or s, or chars */
701 /* We *must* use toupper rather than tolower here due to the
702 asynchronous upper to lower mapping.
704 #if !defined(KANJI_WIN95_COMPATIBILITY)
706 * For completeness we should put in equivalent code for code pages
707 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
708 * doubt anyone wants Samba to behave differently from Win95 and WinNT
709 * here. They both treat full width ascii characters as case senstive
710 * filenames (ie. they don't do the work we do here).
714 if(lp_client_code_page() == KANJI_CODEPAGE)
716 /* Win95 treats full width ascii characters as case sensitive. */
721 return toupper (*s) - toupper (*t);
722 else if (is_sj_alph (*s) && is_sj_alph (*t))
724 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
731 else if (is_shift_jis (*s) && is_shift_jis (*t))
733 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
736 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
743 else if (is_shift_jis (*s))
745 else if (is_shift_jis (*t))
749 diff = toupper (*s) - toupper (*t);
760 #endif /* KANJI_WIN95_COMPATIBILITY */
762 while (n && *s && *t && toupper(*s) == toupper(*t))
769 /* not run out of chars - strings are different lengths */
771 return(toupper(*s) - toupper(*t));
773 /* identical up to where we run out of chars,
774 and strings are same length */
779 /*******************************************************************
781 ********************************************************************/
782 BOOL strequal(char *s1, char *s2)
784 if (s1 == s2) return(True);
785 if (!s1 || !s2) return(False);
787 return(StrCaseCmp(s1,s2)==0);
790 /*******************************************************************
791 compare 2 strings up to and including the nth char.
792 ******************************************************************/
793 BOOL strnequal(char *s1,char *s2,int n)
795 if (s1 == s2) return(True);
796 if (!s1 || !s2 || !n) return(False);
798 return(StrnCaseCmp(s1,s2,n)==0);
801 /*******************************************************************
802 compare 2 strings (case sensitive)
803 ********************************************************************/
804 BOOL strcsequal(char *s1,char *s2)
806 if (s1 == s2) return(True);
807 if (!s1 || !s2) return(False);
809 return(strcmp(s1,s2)==0);
813 /*******************************************************************
814 convert a string to lower case
815 ********************************************************************/
816 void strlower(char *s)
820 #if !defined(KANJI_WIN95_COMPATIBILITY)
822 * For completeness we should put in equivalent code for code pages
823 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
824 * doubt anyone wants Samba to behave differently from Win95 and WinNT
825 * here. They both treat full width ascii characters as case senstive
826 * filenames (ie. they don't do the work we do here).
830 if(lp_client_code_page() == KANJI_CODEPAGE)
832 /* Win95 treats full width ascii characters as case sensitive. */
833 if (is_shift_jis (*s))
835 if (is_sj_upper (s[0], s[1]))
836 s[1] = sj_tolower2 (s[1]);
839 else if (is_kana (*s))
851 #endif /* KANJI_WIN95_COMPATIBILITY */
853 int skip = skip_multibyte_char( *s );
866 /*******************************************************************
867 convert a string to upper case
868 ********************************************************************/
869 void strupper(char *s)
873 #if !defined(KANJI_WIN95_COMPATIBILITY)
875 * For completeness we should put in equivalent code for code pages
876 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
877 * doubt anyone wants Samba to behave differently from Win95 and WinNT
878 * here. They both treat full width ascii characters as case senstive
879 * filenames (ie. they don't do the work we do here).
883 if(lp_client_code_page() == KANJI_CODEPAGE)
885 /* Win95 treats full width ascii characters as case sensitive. */
886 if (is_shift_jis (*s))
888 if (is_sj_lower (s[0], s[1]))
889 s[1] = sj_toupper2 (s[1]);
892 else if (is_kana (*s))
904 #endif /* KANJI_WIN95_COMPATIBILITY */
906 int skip = skip_multibyte_char( *s );
919 /*******************************************************************
920 convert a string to "normal" form
921 ********************************************************************/
922 void strnorm(char *s)
924 if (case_default == CASE_UPPER)
930 /*******************************************************************
931 check if a string is in "normal" case
932 ********************************************************************/
933 BOOL strisnormal(char *s)
935 if (case_default == CASE_UPPER)
936 return(!strhaslower(s));
938 return(!strhasupper(s));
942 /****************************************************************************
944 ****************************************************************************/
945 void string_replace(char *s,char oldc,char newc)
950 skip = skip_multibyte_char( *s );
962 /****************************************************************************
963 make a file into unix format
964 ****************************************************************************/
965 void unix_format(char *fname)
967 string_replace(fname,'\\','/');
970 /****************************************************************************
971 make a file into dos format
972 ****************************************************************************/
973 void dos_format(char *fname)
975 string_replace(fname,'/','\\');
978 /*******************************************************************
979 show a smb message structure
980 ********************************************************************/
981 void show_msg(char *buf)
986 if (DEBUGLEVEL < 5) return;
988 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
990 (int)CVAL(buf,smb_com),
991 (int)CVAL(buf,smb_rcls),
992 (int)CVAL(buf,smb_reh),
993 (int)SVAL(buf,smb_err),
994 (int)CVAL(buf,smb_flg),
995 (int)SVAL(buf,smb_flg2)));
996 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
997 (int)SVAL(buf,smb_tid),
998 (int)SVAL(buf,smb_pid),
999 (int)SVAL(buf,smb_uid),
1000 (int)SVAL(buf,smb_mid),
1001 (int)CVAL(buf,smb_wct)));
1003 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1005 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1006 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1009 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1011 DEBUG(5,("smb_bcc=%d\n",bcc));
1013 if (DEBUGLEVEL < 10) return;
1015 if (DEBUGLEVEL < 50)
1017 bcc = MIN(bcc, 512);
1020 dump_data(10, smb_buf(buf), bcc);
1022 /*******************************************************************
1023 return the length of an smb packet
1024 ********************************************************************/
1025 int smb_len(char *buf)
1027 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1030 /*******************************************************************
1031 set the length of an smb packet
1032 ********************************************************************/
1033 void _smb_setlen(char *buf,int len)
1036 buf[1] = (len&0x10000)>>16;
1037 buf[2] = (len&0xFF00)>>8;
1041 /*******************************************************************
1042 set the length and marker of an smb packet
1043 ********************************************************************/
1044 void smb_setlen(char *buf,int len)
1046 _smb_setlen(buf,len);
1054 /*******************************************************************
1055 setup the word count and byte count for a smb message
1056 ********************************************************************/
1057 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1060 bzero(buf + smb_size,num_words*2 + num_bytes);
1061 CVAL(buf,smb_wct) = num_words;
1062 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1063 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1064 return (smb_size + num_words*2 + num_bytes);
1067 /*******************************************************************
1068 return the number of smb words
1069 ********************************************************************/
1070 static int smb_numwords(char *buf)
1072 return (CVAL(buf,smb_wct));
1075 /*******************************************************************
1076 return the size of the smb_buf region of a message
1077 ********************************************************************/
1078 int smb_buflen(char *buf)
1080 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1083 /*******************************************************************
1084 return a pointer to the smb_buf data area
1085 ********************************************************************/
1086 static int smb_buf_ofs(char *buf)
1088 return (smb_size + CVAL(buf,smb_wct)*2);
1091 /*******************************************************************
1092 return a pointer to the smb_buf data area
1093 ********************************************************************/
1094 char *smb_buf(char *buf)
1096 return (buf + smb_buf_ofs(buf));
1099 /*******************************************************************
1100 return the SMB offset into an SMB buffer
1101 ********************************************************************/
1102 int smb_offset(char *p,char *buf)
1104 return(PTR_DIFF(p,buf+4) + chain_size);
1108 /*******************************************************************
1109 skip past some strings in a buffer
1110 ********************************************************************/
1111 char *skip_string(char *buf,int n)
1114 buf += strlen(buf) + 1;
1118 /*******************************************************************
1119 trim the specified elements off the front and back of a string
1120 ********************************************************************/
1121 BOOL trim_string(char *s,char *front,char *back)
1124 size_t front_len = (front && *front) ? strlen(front) : 0;
1125 size_t back_len = (back && *back) ? strlen(back) : 0;
1128 while (front_len && strncmp(s, front, front_len) == 0)
1134 if (!(*p = p[front_len]))
1141 while (back_len && s_len >= back_len &&
1142 (strncmp(s + s_len - back_len, back, back_len)==0))
1145 s[s_len - back_len] = 0;
1152 /*******************************************************************
1153 reduce a file name, removing .. elements.
1154 ********************************************************************/
1155 void dos_clean_name(char *s)
1159 DEBUG(3,("dos_clean_name [%s]\n",s));
1161 /* remove any double slashes */
1162 string_sub(s, "\\\\", "\\");
1164 while ((p = strstr(s,"\\..\\")) != NULL)
1171 if ((p=strrchr(s,'\\')) != NULL)
1178 trim_string(s,NULL,"\\..");
1180 string_sub(s, "\\.\\", "\\");
1183 /*******************************************************************
1184 reduce a file name, removing .. elements.
1185 ********************************************************************/
1186 void unix_clean_name(char *s)
1190 DEBUG(3,("unix_clean_name [%s]\n",s));
1192 /* remove any double slashes */
1193 string_sub(s, "//","/");
1195 /* Remove leading ./ characters */
1196 if(strncmp(s, "./", 2) == 0) {
1197 trim_string(s, "./", NULL);
1202 while ((p = strstr(s,"/../")) != NULL)
1209 if ((p=strrchr(s,'/')) != NULL)
1216 trim_string(s,NULL,"/..");
1220 /*******************************************************************
1221 a wrapper for the normal chdir() function
1222 ********************************************************************/
1223 int ChDir(char *path)
1226 static pstring LastDir="";
1228 if (strcsequal(path,".")) return(0);
1230 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1231 DEBUG(3,("chdir to %s\n",path));
1232 res = dos_chdir(path);
1234 pstrcpy(LastDir,path);
1238 /* number of list structures for a caching GetWd function. */
1239 #define MAX_GETWDCACHE (50)
1243 SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
1244 SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
1245 char *text; /* The pathname in DOS format. */
1247 } ino_list[MAX_GETWDCACHE];
1249 BOOL use_getwd_cache=True;
1251 /*******************************************************************
1252 return the absolute current directory path - given a UNIX pathname.
1253 Note that this path is returned in DOS format, not UNIX
1255 ********************************************************************/
1256 char *GetWd(char *str)
1259 static BOOL getwd_cache_init = False;
1260 SMB_STRUCT_STAT st, st2;
1265 if (!use_getwd_cache)
1266 return(dos_getwd(str));
1268 /* init the cache */
1269 if (!getwd_cache_init)
1271 getwd_cache_init = True;
1272 for (i=0;i<MAX_GETWDCACHE;i++)
1274 string_init(&ino_list[i].text,"");
1275 ino_list[i].valid = False;
1279 /* Get the inode of the current directory, if this doesn't work we're
1282 if (dos_stat(".",&st) == -1)
1284 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1285 return(dos_getwd(str));
1289 for (i=0; i<MAX_GETWDCACHE; i++)
1290 if (ino_list[i].valid)
1293 /* If we have found an entry with a matching inode and dev number
1294 then find the inode number for the directory in the cached string.
1295 If this agrees with that returned by the stat for the current
1296 directory then all is o.k. (but make sure it is a directory all
1299 if (st.st_ino == ino_list[i].inode &&
1300 st.st_dev == ino_list[i].dev)
1302 if (dos_stat(ino_list[i].text,&st2) == 0)
1304 if (st.st_ino == st2.st_ino &&
1305 st.st_dev == st2.st_dev &&
1306 (st2.st_mode & S_IFMT) == S_IFDIR)
1308 pstrcpy (str, ino_list[i].text);
1310 /* promote it for future use */
1311 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1316 /* If the inode is different then something's changed,
1317 scrub the entry and start from scratch. */
1318 ino_list[i].valid = False;
1325 /* We don't have the information to hand so rely on traditional methods.
1326 The very slow getcwd, which spawns a process on some systems, or the
1327 not quite so bad getwd. */
1331 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1337 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1339 /* add it to the cache */
1340 i = MAX_GETWDCACHE - 1;
1341 string_set(&ino_list[i].text,s);
1342 ino_list[i].dev = st.st_dev;
1343 ino_list[i].inode = st.st_ino;
1344 ino_list[i].valid = True;
1346 /* put it at the top of the list */
1347 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1354 /*******************************************************************
1355 reduce a file name, removing .. elements and checking that
1356 it is below dir in the heirachy. This uses GetWd() and so must be run
1357 on the system that has the referenced file system.
1359 widelinks are allowed if widelinks is true
1360 ********************************************************************/
1361 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1363 #ifndef REDUCE_PATHS
1371 BOOL relative = (*s != '/');
1373 *dir2 = *wd = *base_name = *newname = 0;
1378 /* can't have a leading .. */
1379 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1381 DEBUG(3,("Illegal file name? (%s)\n",s));
1391 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1393 /* remove any double slashes */
1394 string_sub(s,"//","/");
1396 pstrcpy(base_name,s);
1397 p = strrchr(base_name,'/');
1404 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1408 if (ChDir(dir) != 0)
1410 DEBUG(0,("couldn't chdir to %s\n",dir));
1416 DEBUG(0,("couldn't getwd for %s\n",dir));
1422 if (p && (p != base_name))
1425 if (strcmp(p+1,".")==0)
1427 if (strcmp(p+1,"..")==0)
1431 if (ChDir(base_name) != 0)
1434 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1438 if (!GetWd(newname))
1441 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1445 if (p && (p != base_name))
1447 pstrcat(newname,"/");
1448 pstrcat(newname,p+1);
1452 int l = strlen(dir2);
1453 if (dir2[l-1] == '/')
1456 if (strncmp(newname,dir2,l) != 0)
1459 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1465 if (newname[l] == '/')
1466 pstrcpy(s,newname + l + 1);
1468 pstrcpy(s,newname+l);
1479 DEBUG(3,("reduced to %s\n",s));
1484 /****************************************************************************
1486 ****************************************************************************/
1487 static void expand_one(char *Mask,int len)
1490 while ((p1 = strchr(Mask,'*')) != NULL)
1492 int lfill = (len+1) - strlen(Mask);
1493 int l1= (p1 - Mask);
1496 memset(tmp+l1,'?',lfill);
1497 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1502 /****************************************************************************
1503 parse out a directory name from a path name. Assumes dos style filenames.
1504 ****************************************************************************/
1505 static char *dirname_dos(char *path,char *buf)
1507 char *p = strrchr(path,'\\');
1522 /****************************************************************************
1523 expand a wildcard expression, replacing *s with ?s
1524 ****************************************************************************/
1525 void expand_mask(char *Mask,BOOL doext)
1530 BOOL hasdot = False;
1532 BOOL absolute = (*Mask == '\\');
1534 *mbeg = *mext = *dirpart = *filepart = 0;
1536 /* parse the directory and filename */
1537 if (strchr(Mask,'\\'))
1538 dirname_dos(Mask,dirpart);
1540 filename_dos(Mask,filepart);
1542 pstrcpy(mbeg,filepart);
1543 if ((p1 = strchr(mbeg,'.')) != NULL)
1553 if (strlen(mbeg) > 8)
1555 pstrcpy(mext,mbeg + 8);
1561 pstrcpy(mbeg,"????????");
1562 if ((*mext == 0) && doext && !hasdot)
1563 pstrcpy(mext,"???");
1565 if (strequal(mbeg,"*") && *mext==0)
1573 pstrcpy(Mask,dirpart);
1574 if (*dirpart || absolute) pstrcat(Mask,"\\");
1579 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1583 /****************************************************************************
1584 does a string have any uppercase chars in it?
1585 ****************************************************************************/
1586 BOOL strhasupper(char *s)
1590 #if !defined(KANJI_WIN95_COMPATIBILITY)
1592 * For completeness we should put in equivalent code for code pages
1593 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1594 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1595 * here. They both treat full width ascii characters as case senstive
1596 * filenames (ie. they don't do the work we do here).
1600 if(lp_client_code_page() == KANJI_CODEPAGE)
1602 /* Win95 treats full width ascii characters as case sensitive. */
1603 if (is_shift_jis (*s))
1605 else if (is_kana (*s))
1615 #endif /* KANJI_WIN95_COMPATIBILITY */
1617 int skip = skip_multibyte_char( *s );
1630 /****************************************************************************
1631 does a string have any lowercase chars in it?
1632 ****************************************************************************/
1633 BOOL strhaslower(char *s)
1637 #if !defined(KANJI_WIN95_COMPATIBILITY)
1639 * For completeness we should put in equivalent code for code pages
1640 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1641 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1642 * here. They both treat full width ascii characters as case senstive
1643 * filenames (ie. they don't do the work we do here).
1647 if(lp_client_code_page() == KANJI_CODEPAGE)
1649 /* Win95 treats full width ascii characters as case sensitive. */
1650 if (is_shift_jis (*s))
1652 if (is_sj_upper (s[0], s[1]))
1654 if (is_sj_lower (s[0], s[1]))
1658 else if (is_kana (*s))
1670 #endif /* KANJI_WIN95_COMPATIBILITY */
1672 int skip = skip_multibyte_char( *s );
1685 /****************************************************************************
1686 find the number of chars in a string
1687 ****************************************************************************/
1688 int count_chars(char *s,char c)
1692 #if !defined(KANJI_WIN95_COMPATIBILITY)
1694 * For completeness we should put in equivalent code for code pages
1695 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1696 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1697 * here. They both treat full width ascii characters as case senstive
1698 * filenames (ie. they don't do the work we do here).
1702 if(lp_client_code_page() == KANJI_CODEPAGE)
1704 /* Win95 treats full width ascii characters as case sensitive. */
1707 if (is_shift_jis (*s))
1718 #endif /* KANJI_WIN95_COMPATIBILITY */
1722 int skip = skip_multibyte_char( *s );
1736 /****************************************************************************
1738 ****************************************************************************/
1739 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
1744 pstrcpy(mask2,mask);
1746 if ((mode & aDIR) != 0)
1749 memset(buf+1,' ',11);
1750 if ((p = strchr(mask2,'.')) != NULL)
1753 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1754 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1758 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1760 bzero(buf+21,DIR_STRUCT_SIZE-21);
1761 CVAL(buf,21) = mode;
1762 put_dos_date(buf,22,date);
1763 SSVAL(buf,26,size & 0xFFFF);
1764 SSVAL(buf,28,(size >> 16)&0xFFFF);
1765 StrnCpy(buf+30,fname,12);
1766 if (!case_sensitive)
1768 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1772 /*******************************************************************
1773 close the low 3 fd's and open dev/null in their place
1774 ********************************************************************/
1775 void close_low_fds(void)
1779 close(0); close(1); close(2);
1780 /* try and use up these file descriptors, so silly
1781 library routines writing to stdout etc won't cause havoc */
1783 fd = open("/dev/null",O_RDWR,0);
1784 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1786 DEBUG(0,("Can't open /dev/null\n"));
1790 DEBUG(0,("Didn't get file descriptor %d\n",i));
1796 /****************************************************************************
1797 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1799 if SYSV use O_NDELAY
1801 ****************************************************************************/
1802 static int set_blocking(int fd, BOOL set)
1806 #define FLAG_TO_SET O_NONBLOCK
1809 #define FLAG_TO_SET O_NDELAY
1811 #define FLAG_TO_SET FNDELAY
1815 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1817 if(set) /* Turn blocking on - ie. clear nonblock flag */
1818 val &= ~FLAG_TO_SET;
1821 return fcntl( fd, F_SETFL, val);
1826 /****************************************************************************
1828 ****************************************************************************/
1829 ssize_t write_socket(int fd,char *buf,size_t len)
1835 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1836 ret = write_data(fd,buf,len);
1838 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1840 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
1841 len, fd, strerror(errno) ));
1846 /****************************************************************************
1848 ****************************************************************************/
1849 ssize_t read_udp_socket(int fd,char *buf,size_t len)
1852 struct sockaddr_in sock;
1855 socklen = sizeof(sock);
1856 bzero((char *)&sock,socklen);
1857 bzero((char *)&lastip,sizeof(lastip));
1858 ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1860 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1864 lastip = sock.sin_addr;
1865 lastport = ntohs(sock.sin_port);
1867 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1868 inet_ntoa(lastip), lastport, ret));
1873 /****************************************************************************
1874 read data from a device with a timout in msec.
1875 mincount = if timeout, minimum to read before returning
1876 maxcount = number to be read.
1877 time_out = timeout in milliseconds
1878 ****************************************************************************/
1880 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
1886 struct timeval timeout;
1888 /* just checking .... */
1889 if (maxcnt <= 0) return(0);
1894 if (time_out <= 0) {
1895 if (mincnt == 0) mincnt = maxcnt;
1897 while (nread < mincnt) {
1900 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1902 readret = read(fd, buf + nread, maxcnt - nread);
1904 #else /* WITH_SSL */
1905 readret = read(fd, buf + nread, maxcnt - nread);
1906 #endif /* WITH_SSL */
1909 smb_read_error = READ_EOF;
1913 if (readret == -1) {
1914 smb_read_error = READ_ERROR;
1919 return((ssize_t)nread);
1922 /* Most difficult - timeout read */
1923 /* If this is ever called on a disk file and
1924 mincnt is greater then the filesize then
1925 system performance will suffer severely as
1926 select always returns true on disk files */
1928 /* Set initial timeout */
1929 timeout.tv_sec = (time_t)(time_out / 1000);
1930 timeout.tv_usec = (long)(1000 * (time_out % 1000));
1932 for (nread=0; nread < mincnt; )
1937 selrtn = sys_select(fd+1,&fds,&timeout);
1939 /* Check if error */
1941 /* something is wrong. Maybe the socket is dead? */
1942 smb_read_error = READ_ERROR;
1946 /* Did we timeout ? */
1948 smb_read_error = READ_TIMEOUT;
1954 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1956 readret = read(fd, buf + nread, maxcnt - nread);
1958 #else /* WITH_SSL */
1959 readret = read(fd, buf+nread, maxcnt-nread);
1960 #endif /* WITH_SSL */
1963 /* we got EOF on the file descriptor */
1964 smb_read_error = READ_EOF;
1968 if (readret == -1) {
1969 /* the descriptor is probably dead */
1970 smb_read_error = READ_ERROR;
1977 /* Return the number we got */
1978 return((ssize_t)nread);
1981 /*******************************************************************
1982 find the difference in milliseconds between two struct timeval
1984 ********************************************************************/
1985 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1987 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1988 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1991 /****************************************************************************
1992 send a keepalive packet (rfc1002)
1993 ****************************************************************************/
1994 BOOL send_keepalive(int client)
1996 unsigned char buf[4];
1999 buf[1] = buf[2] = buf[3] = 0;
2001 return(write_data(client,(char *)buf,4) == 4);
2006 /****************************************************************************
2007 read data from the client, reading exactly N bytes.
2008 ****************************************************************************/
2009 ssize_t read_data(int fd,char *buffer,size_t N)
2020 ret = SSL_read(ssl, buffer + total, N - total);
2022 ret = read(fd,buffer + total,N - total);
2024 #else /* WITH_SSL */
2025 ret = read(fd,buffer + total,N - total);
2026 #endif /* WITH_SSL */
2030 smb_read_error = READ_EOF;
2035 smb_read_error = READ_ERROR;
2040 return (ssize_t)total;
2044 /****************************************************************************
2046 ****************************************************************************/
2047 ssize_t write_data(int fd,char *buffer,size_t N)
2056 ret = SSL_write(ssl,buffer + total,N - total);
2058 ret = write(fd,buffer + total,N - total);
2060 #else /* WITH_SSL */
2061 ret = write(fd,buffer + total,N - total);
2062 #endif /* WITH_SSL */
2064 if (ret == -1) return -1;
2065 if (ret == 0) return total;
2069 return (ssize_t)total;
2073 /****************************************************************************
2074 transfer some data between two fd's
2075 ****************************************************************************/
2076 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
2078 static char *buf=NULL;
2081 SMB_OFF_T total = 0;
2083 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
2086 size = lp_readsize();
2087 size = MAX(size,1024);
2090 while (!buf && size>0) {
2091 buf = (char *)Realloc(buf,size+8);
2092 if (!buf) size /= 2;
2096 DEBUG(0,("Can't allocate transfer buffer!\n"));
2100 abuf = buf + (align%8);
2107 int s = (int)MIN(n,(SMB_OFF_T)size);
2112 if (header && (headlen >= MIN(s,1024))) {
2122 if (header && headlen > 0)
2124 ret = MIN(headlen,size);
2125 memcpy(buf1,header,ret);
2128 if (headlen <= 0) header = NULL;
2132 ret += read(infd,buf1+ret,s-ret);
2136 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2137 if (ret2 > 0) total += ret2;
2138 /* if we can't write then dump excess data */
2140 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2142 if (ret <= 0 || ret2 != ret)
2150 /****************************************************************************
2151 read 4 bytes of a smb packet and return the smb length of the packet
2152 store the result in the buffer
2153 This version of the function will return a length of zero on receiving
2155 timeout is in milliseconds.
2156 ****************************************************************************/
2157 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
2166 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2168 ok = (read_data(fd,inbuf,4) == 4);
2173 len = smb_len(inbuf);
2174 msg_type = CVAL(inbuf,0);
2176 if (msg_type == 0x85)
2177 DEBUG(5,("Got keepalive packet\n"));
2180 DEBUG(10,("got smb length of %d\n",len));
2185 /****************************************************************************
2186 read 4 bytes of a smb packet and return the smb length of the packet
2187 store the result in the buffer. This version of the function will
2188 never return a session keepalive (length of zero).
2189 timeout is in milliseconds.
2190 ****************************************************************************/
2191 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
2197 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2202 /* Ignore session keepalives. */
2203 if(CVAL(inbuf,0) != 0x85)
2210 /****************************************************************************
2211 read an smb from a fd. Note that the buffer *MUST* be of size
2212 BUFFER_SIZE+SAFETY_MARGIN.
2213 The timeout is in milliseconds.
2214 This function will return on a
2215 receipt of a session keepalive packet.
2216 ****************************************************************************/
2217 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
2223 bzero(buffer,smb_size + 100);
2225 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2229 if (len > BUFFER_SIZE) {
2230 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2231 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2236 ret = read_data(fd,buffer+4,len);
2238 smb_read_error = READ_ERROR;
2245 /****************************************************************************
2246 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2247 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2248 The timeout is in milliseconds
2250 This is exactly the same as receive_smb except that it never returns
2251 a session keepalive packet (just as receive_smb used to do).
2252 receive_smb was changed to return keepalives as the oplock processing means this call
2253 should never go into a blocking read.
2254 ****************************************************************************/
2256 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
2262 ret = receive_smb(fd, buffer, timeout);
2267 /* Ignore session keepalive packets. */
2268 if(CVAL(buffer,0) != 0x85)
2274 /****************************************************************************
2276 ****************************************************************************/
2277 BOOL send_smb(int fd,char *buffer)
2282 len = smb_len(buffer) + 4;
2284 while (nwritten < len)
2286 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2289 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2300 /****************************************************************************
2301 find a pointer to a netbios name
2302 ****************************************************************************/
2303 static char *name_ptr(char *buf,int ofs)
2305 unsigned char c = *(unsigned char *)(buf+ofs);
2307 if ((c & 0xC0) == 0xC0)
2311 memcpy(p,buf+ofs,2);
2314 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2321 /****************************************************************************
2322 extract a netbios name from a buf
2323 ****************************************************************************/
2324 int name_extract(char *buf,int ofs,char *name)
2326 char *p = name_ptr(buf,ofs);
2327 int d = PTR_DIFF(p,buf+ofs);
2329 if (d < -50 || d > 50) return(0);
2330 return(name_interpret(p,name));
2333 /****************************************************************************
2334 return the total storage length of a mangled name
2335 ****************************************************************************/
2336 int name_len( char *s )
2340 /* If the two high bits of the byte are set, return 2. */
2341 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2344 /* Add up the length bytes. */
2345 for( len = 1; (*s); s += (*s) + 1 )
2353 /****************************************************************************
2354 send a single packet to a port on another machine
2355 ****************************************************************************/
2356 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2360 struct sockaddr_in sock_out;
2365 /* create a socket to write to */
2366 out_fd = socket(AF_INET, type, 0);
2369 DEBUG(0,("socket failed"));
2373 /* set the address and port */
2374 bzero((char *)&sock_out,sizeof(sock_out));
2375 putip((char *)&sock_out.sin_addr,(char *)&ip);
2376 sock_out.sin_port = htons( port );
2377 sock_out.sin_family = AF_INET;
2380 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2381 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2384 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2387 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2388 inet_ntoa(ip),port,strerror(errno)));
2394 /*******************************************************************
2395 sleep for a specified number of milliseconds
2396 ********************************************************************/
2397 static void msleep(int t)
2400 struct timeval tval,t1,t2;
2407 tval.tv_sec = (t-tdiff)/1000;
2408 tval.tv_usec = 1000*((t-tdiff)%1000);
2412 sys_select(0,&fds,&tval);
2415 tdiff = TvalDiff(&t1,&t2);
2419 /****************************************************************************
2420 check if a string is part of a list
2421 ****************************************************************************/
2422 BOOL in_list(char *s,char *list,BOOL casesensitive)
2427 if (!list) return(False);
2429 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
2430 if (casesensitive) {
2431 if (strcmp(tok,s) == 0)
2434 if (StrCaseCmp(tok,s) == 0)
2441 /* this is used to prevent lots of mallocs of size 1 */
2442 static char *null_string = NULL;
2444 /****************************************************************************
2445 set a string value, allocing the space for the string
2446 ****************************************************************************/
2447 BOOL string_init(char **dest,char *src)
2458 if((null_string = (char *)malloc(1)) == NULL) {
2459 DEBUG(0,("string_init: malloc fail for null_string.\n"));
2464 *dest = null_string;
2468 (*dest) = (char *)malloc(l+1);
2469 if ((*dest) == NULL) {
2470 DEBUG(0,("Out of memory in string_init\n"));
2479 /****************************************************************************
2481 ****************************************************************************/
2482 void string_free(char **s)
2484 if (!s || !(*s)) return;
2485 if (*s == null_string)
2491 /****************************************************************************
2492 set a string value, allocing the space for the string, and deallocating any
2494 ****************************************************************************/
2495 BOOL string_set(char **dest,char *src)
2499 return(string_init(dest,src));
2502 /****************************************************************************
2503 substitute a string for a pattern in another string. Make sure there is
2506 This routine looks for pattern in s and replaces it with
2507 insert. It may do multiple replacements.
2509 return True if a substitution was done.
2510 ****************************************************************************/
2511 BOOL string_sub(char *s,char *pattern,char *insert)
2517 if (!insert || !pattern || !s) return(False);
2520 lp = strlen(pattern);
2521 li = strlen(insert);
2523 if (!*pattern) return(False);
2525 while (lp <= ls && (p = strstr(s,pattern)))
2528 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2529 memcpy(p,insert,li);
2536 /*********************************************************
2537 * Recursive routine that is called by unix_mask_match.
2538 * Does the actual matching. This is the 'original code'
2539 * used by the unix matcher.
2540 *********************************************************/
2541 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2545 for( p = regexp; *p && *str; ) {
2552 /* Look for a character matching
2553 the one after the '*' */
2556 return True; /* Automatic match */
2558 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2560 if(unix_do_match(str,p,case_sig))
2574 if(toupper(*str) != toupper(*p))
2584 if (!*p && str[0] == '.' && str[1] == 0)
2587 if (!*str && *p == '?')
2589 while (*p == '?') p++;
2593 if(!*str && (*p == '*' && p[1] == '\0'))
2599 /*********************************************************
2600 * Routine to match a given string with a regexp - uses
2601 * simplified regexp that takes * and ? only. Case can be
2602 * significant or not.
2603 * This is the 'original code' used by the unix matcher.
2604 *********************************************************/
2606 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2610 fstring ebase,eext,sbase,sext;
2614 /* Make local copies of str and regexp */
2615 StrnCpy(p1,regexp,sizeof(pstring)-1);
2616 StrnCpy(p2,str,sizeof(pstring)-1);
2618 if (!strchr(p2,'.')) {
2622 /* Remove any *? and ** as they are meaningless */
2623 for(p = p1; *p; p++)
2624 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2625 (void)pstrcpy( &p[1], &p[2]);
2627 if (strequal(p1,"*")) return(True);
2629 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2635 if ((p=strrchr(p1,'.'))) {
2644 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2654 matched = unix_do_match(sbase,ebase,case_sig) &&
2655 (trans2 || unix_do_match(sext,eext,case_sig));
2657 DEBUG(8,("unix_mask_match returning %d\n", matched));
2662 /*********************************************************
2663 * Recursive routine that is called by mask_match.
2664 * Does the actual matching. Returns True if matched,
2665 * False if failed. This is the 'new' NT style matcher.
2666 *********************************************************/
2668 BOOL do_match(char *str, char *regexp, int case_sig)
2672 for( p = regexp; *p && *str; ) {
2679 /* Look for a character matching
2680 the one after the '*' */
2683 return True; /* Automatic match */
2685 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2687 /* Now eat all characters that match, as
2688 we want the *last* character to match. */
2689 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2691 str--; /* We've eaten the match char after the '*' */
2692 if(do_match(str,p,case_sig)) {
2709 if(toupper(*str) != toupper(*p)) {
2721 if (!*p && str[0] == '.' && str[1] == 0) {
2725 if (!*str && *p == '?') {
2731 if(!*str && (*p == '*' && p[1] == '\0')) {
2739 /*********************************************************
2740 * Routine to match a given string with a regexp - uses
2741 * simplified regexp that takes * and ? only. Case can be
2742 * significant or not.
2743 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2744 * This is the new 'NT style' matcher.
2745 *********************************************************/
2747 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2750 pstring t_pattern, t_filename, te_pattern, te_filename;
2751 fstring ebase,eext,sbase,sext;
2753 BOOL matched = False;
2755 /* Make local copies of str and regexp */
2756 pstrcpy(t_pattern,regexp);
2757 pstrcpy(t_filename,str);
2761 * Not sure if this is a good idea. JRA.
2763 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2768 if (!strchr(t_filename,'.')) {
2769 pstrcat(t_filename,".");
2773 /* Remove any *? and ** as they are meaningless */
2774 string_sub(t_pattern, "*?", "*");
2775 string_sub(t_pattern, "**", "*");
2777 if (strequal(t_pattern,"*"))
2780 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2784 * Match each component of the regexp, split up by '.'
2787 char *fp, *rp, *cp2, *cp1;
2788 BOOL last_wcard_was_star = False;
2789 int num_path_components, num_regexp_components;
2791 pstrcpy(te_pattern,t_pattern);
2792 pstrcpy(te_filename,t_filename);
2794 * Remove multiple "*." patterns.
2796 string_sub(te_pattern, "*.*.", "*.");
2797 num_regexp_components = count_chars(te_pattern, '.');
2798 num_path_components = count_chars(te_filename, '.');
2801 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2803 if(num_regexp_components == 0)
2804 matched = do_match( te_filename, te_pattern, case_sig);
2806 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
2807 fp = strchr(cp2, '.');
2810 rp = strchr(cp1, '.');
2814 if(cp1[strlen(cp1)-1] == '*')
2815 last_wcard_was_star = True;
2817 last_wcard_was_star = False;
2819 if(!do_match(cp2, cp1, case_sig))
2822 cp1 = rp ? rp + 1 : NULL;
2823 cp2 = fp ? fp + 1 : "";
2825 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
2826 /* Eat the extra path components. */
2829 for(i = 0; i < num_path_components - num_regexp_components; i++) {
2830 fp = strchr(cp2, '.');
2834 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
2835 cp2 = fp ? fp + 1 : "";
2838 cp2 = fp ? fp + 1 : "";
2840 num_path_components -= i;
2843 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
2848 /* -------------------------------------------------
2849 * Behaviour of Win95
2850 * for 8.3 filenames and 8.3 Wildcards
2851 * -------------------------------------------------
2853 if (strequal (t_filename, ".")) {
2855 * Patterns: *.* *. ?. ? are valid
2858 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2859 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
2861 } else if (strequal (t_filename, "..")) {
2863 * Patterns: *.* *. ?. ? *.? are valid
2866 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2867 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
2868 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
2872 if ((p = strrchr (t_pattern, '.'))) {
2874 * Wildcard has a suffix.
2877 fstrcpy (ebase, t_pattern);
2879 fstrcpy (eext, p + 1);
2881 /* pattern ends in DOT: treat as if there is no DOT */
2883 if (strequal (ebase, "*"))
2888 * No suffix for wildcard.
2890 fstrcpy (ebase, t_pattern);
2894 p = strrchr (t_filename, '.');
2895 if (p && (p[1] == 0) ) {
2897 * Filename has an extension of '.' only.
2899 *p = 0; /* nuke dot at end of string */
2900 p = 0; /* and treat it as if there is no extension */
2905 * Filename has an extension.
2908 fstrcpy (sbase, t_filename);
2909 fstrcpy (sext, p + 1);
2911 matched = do_match(sbase, ebase, case_sig)
2912 && do_match(sext, eext, case_sig);
2914 /* pattern has no extension */
2915 /* Really: match complete filename with pattern ??? means exactly 3 chars */
2916 matched = do_match(str, ebase, case_sig);
2920 * Filename has no extension.
2922 fstrcpy (sbase, t_filename);
2925 /* pattern has extension */
2926 matched = do_match(sbase, ebase, case_sig)
2927 && do_match(sext, eext, case_sig);
2929 matched = do_match(sbase, ebase, case_sig);
2930 #ifdef EMULATE_WEIRD_W95_MATCHING
2932 * Even Microsoft has some problems
2933 * Behaviour Win95 -> local disk
2934 * is different from Win95 -> smb drive from Nt 4.0
2935 * This branch would reflect the Win95 local disk behaviour
2938 /* a? matches aa and a in w95 */
2939 fstrcat (sbase, ".");
2940 matched = do_match(sbase, ebase, case_sig);
2948 DEBUG(8,("mask_match returning %d\n", matched));
2953 /****************************************************************************
2954 become a daemon, discarding the controlling terminal
2955 ****************************************************************************/
2956 void become_daemon(void)
2962 /* detach from the terminal */
2965 #elif defined(TIOCNOTTY)
2967 int i = open("/dev/tty", O_RDWR);
2969 ioctl(i, (int) TIOCNOTTY, (char *)0);
2973 #endif /* HAVE_SETSID */
2975 /* Close fd's 0,1,2. Needed if started by rsh */
2980 /****************************************************************************
2981 put up a yes/no prompt
2982 ****************************************************************************/
2988 if (!fgets(ans,sizeof(ans)-1,stdin))
2991 if (*ans == 'y' || *ans == 'Y')
2997 /****************************************************************************
2998 read a line from a file with possible \ continuation chars.
2999 Blanks at the start or end of a line are stripped.
3000 The string will be allocated if s2 is NULL
3001 ****************************************************************************/
3002 char *fgets_slash(char *s2,int maxlen,FILE *f)
3007 BOOL start_of_line = True;
3014 maxlen = MIN(maxlen,8);
3015 s = (char *)Realloc(s,maxlen);
3018 if (!s || maxlen < 2) return(NULL);
3022 while (len < maxlen-1)
3030 while (len > 0 && s[len-1] == ' ')
3034 if (len > 0 && s[len-1] == '\\')
3037 start_of_line = True;
3042 if (len <= 0 && !s2)
3044 return(len>0?s:NULL);
3049 start_of_line = False;
3053 if (!s2 && len > maxlen-3)
3056 s = (char *)Realloc(s,maxlen);
3057 if (!s) return(NULL);
3065 /****************************************************************************
3066 set the length of a file from a filedescriptor.
3067 Returns 0 on success, -1 on failure.
3068 ****************************************************************************/
3069 int set_filelen(int fd, SMB_OFF_T len)
3071 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3072 extend a file with ftruncate. Provide alternate implementation
3075 #ifdef HAVE_FTRUNCATE_EXTEND
3076 return sys_ftruncate(fd, len);
3080 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
3084 /* Do an fstat to see if the file is longer than
3085 the requested size (call ftruncate),
3086 or shorter, in which case seek to len - 1 and write 1
3088 if(sys_fstat(fd, &st)<0)
3092 if (S_ISFIFO(st.st_mode)) return 0;
3095 if(st.st_size == len)
3097 if(st.st_size > len)
3098 return sys_ftruncate(fd, len);
3100 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
3102 if(write(fd, &c, 1)!=1)
3104 /* Seek to where we were */
3105 sys_lseek(fd, currpos, SEEK_SET);
3112 /****************************************************************************
3113 this is a version of setbuffer() for those machines that only have setvbuf
3114 ****************************************************************************/
3115 void setbuffer(FILE *f,char *buf,int bufsize)
3117 setvbuf(f,buf,_IOFBF,bufsize);
3122 /****************************************************************************
3123 parse out a filename from a path name. Assumes dos style filenames.
3124 ****************************************************************************/
3125 static char *filename_dos(char *path,char *buf)
3127 char *p = strrchr(path,'\\');
3139 /****************************************************************************
3140 expand a pointer to be a particular size
3141 ****************************************************************************/
3142 void *Realloc(void *p,size_t size)
3148 DEBUG(5,("Realloc asked for 0 bytes\n"));
3153 ret = (void *)malloc(size);
3155 ret = (void *)realloc(p,size);
3158 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3164 /****************************************************************************
3165 get my own name and IP
3166 ****************************************************************************/
3167 BOOL get_myname(char *my_name,struct in_addr *ip)
3174 /* get my host name */
3175 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3177 DEBUG(0,("gethostname failed\n"));
3182 if ((hp = Get_Hostbyname(hostname)) == 0)
3184 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3190 /* split off any parts after an initial . */
3191 char *p = strchr(hostname,'.');
3194 fstrcpy(my_name,hostname);
3198 putip((char *)ip,(char *)hp->h_addr);
3204 /****************************************************************************
3205 true if two IP addresses are equal
3206 ****************************************************************************/
3207 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3210 a1 = ntohl(ip1.s_addr);
3211 a2 = ntohl(ip2.s_addr);
3216 /****************************************************************************
3217 open a socket of the specified type, port and address for incoming data
3218 ****************************************************************************/
3219 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3222 struct sockaddr_in sock;
3226 /* get my host name */
3227 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3228 { DEBUG(0,("gethostname failed\n")); return -1; }
3231 if ((hp = Get_Hostbyname(host_name)) == 0)
3233 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3237 bzero((char *)&sock,sizeof(sock));
3238 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3240 #ifdef HAVE_SOCK_SIN_LEN
3241 sock.sin_len = sizeof(sock);
3243 sock.sin_port = htons( port );
3244 sock.sin_family = hp->h_addrtype;
3245 sock.sin_addr.s_addr = socket_addr;
3246 res = socket(hp->h_addrtype, type, 0);
3248 { DEBUG(0,("socket failed\n")); return -1; }
3252 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3255 /* now we've got a socket - we need to bind it */
3256 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3259 if (port == SMB_PORT || port == NMB_PORT)
3260 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3261 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3264 if (dlevel > 0 && port < 1000)
3267 if (port >= 1000 && port < 9000)
3268 return(open_socket_in(type,port+1,dlevel,socket_addr));
3273 DEBUG(3,("bind succeeded on port %d\n",port));
3279 /****************************************************************************
3280 create an outgoing socket
3281 **************************************************************************/
3282 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3284 struct sockaddr_in sock_out;
3286 int connect_loop = 250; /* 250 milliseconds */
3287 int loops = (timeout * 1000) / connect_loop;
3289 /* create a socket to write to */
3290 res = socket(PF_INET, type, 0);
3292 { DEBUG(0,("socket error\n")); return -1; }
3294 if (type != SOCK_STREAM) return(res);
3296 bzero((char *)&sock_out,sizeof(sock_out));
3297 putip((char *)&sock_out.sin_addr,(char *)addr);
3299 sock_out.sin_port = htons( port );
3300 sock_out.sin_family = PF_INET;
3302 /* set it non-blocking */
3303 set_blocking(res,False);
3305 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3307 /* and connect it to the destination */
3309 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3311 /* Some systems return EAGAIN when they mean EINPROGRESS */
3312 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3313 errno == EAGAIN) && loops--) {
3314 msleep(connect_loop);
3318 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3320 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3326 if (ret < 0 && errno == EISCONN) {
3333 DEBUG(1,("error connecting to %s:%d (%s)\n",
3334 inet_ntoa(*addr),port,strerror(errno)));
3339 /* set it blocking again */
3340 set_blocking(res,True);
3346 /****************************************************************************
3347 interpret a protocol description string, with a default
3348 ****************************************************************************/
3349 int interpret_protocol(char *str,int def)
3351 if (strequal(str,"NT1"))
3352 return(PROTOCOL_NT1);
3353 if (strequal(str,"LANMAN2"))
3354 return(PROTOCOL_LANMAN2);
3355 if (strequal(str,"LANMAN1"))
3356 return(PROTOCOL_LANMAN1);
3357 if (strequal(str,"CORE"))
3358 return(PROTOCOL_CORE);
3359 if (strequal(str,"COREPLUS"))
3360 return(PROTOCOL_COREPLUS);
3361 if (strequal(str,"CORE+"))
3362 return(PROTOCOL_COREPLUS);
3364 DEBUG(0,("Unrecognised protocol level %s\n",str));
3370 /****************************************************************************
3371 interpret an internet address or name into an IP address in 4 byte form
3372 ****************************************************************************/
3373 uint32 interpret_addr(char *str)
3378 BOOL pure_address = True;
3380 if (strcmp(str,"0.0.0.0") == 0) return(0);
3381 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3383 for (i=0; pure_address && str[i]; i++)
3384 if (!(isdigit((int)str[i]) || str[i] == '.'))
3385 pure_address = False;
3387 /* if it's in the form of an IP address then get the lib to interpret it */
3389 res = inet_addr(str);
3391 /* otherwise assume it's a network name of some sort and use
3393 if ((hp = Get_Hostbyname(str)) == 0) {
3394 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3397 if(hp->h_addr == NULL) {
3398 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3401 putip((char *)&res,(char *)hp->h_addr);
3404 if (res == (uint32)-1) return(0);
3409 /*******************************************************************
3410 a convenient addition to interpret_addr()
3411 ******************************************************************/
3412 struct in_addr *interpret_addr2(char *str)
3414 static struct in_addr ret;
3415 uint32 a = interpret_addr(str);
3420 /*******************************************************************
3421 check if an IP is the 0.0.0.0
3422 ******************************************************************/
3423 BOOL zero_ip(struct in_addr ip)
3426 putip((char *)&a,(char *)&ip);
3431 /*******************************************************************
3432 matchname - determine if host name matches IP address
3433 ******************************************************************/
3434 static BOOL matchname(char *remotehost,struct in_addr addr)
3439 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3440 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3445 * Make sure that gethostbyname() returns the "correct" host name.
3446 * Unfortunately, gethostbyname("localhost") sometimes yields
3447 * "localhost.domain". Since the latter host name comes from the
3448 * local DNS, we just have to trust it (all bets are off if the local
3449 * DNS is perverted). We always check the address list, though.
3452 if (strcasecmp(remotehost, hp->h_name)
3453 && strcasecmp(remotehost, "localhost")) {
3454 DEBUG(0,("host name/name mismatch: %s != %s",
3455 remotehost, hp->h_name));
3459 /* Look up the host address in the address list we just got. */
3460 for (i = 0; hp->h_addr_list[i]; i++) {
3461 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3466 * The host name does not map to the original host address. Perhaps
3467 * someone has compromised a name server. More likely someone botched
3468 * it, but that could be dangerous, too.
3471 DEBUG(0,("host name/address mismatch: %s != %s",
3472 inet_ntoa(addr), hp->h_name));
3476 /*******************************************************************
3477 Reset the 'done' variables so after a client process is created
3478 from a fork call these calls will be re-done. This should be
3479 expanded if more variables need reseting.
3480 ******************************************************************/
3482 static BOOL global_client_name_done = False;
3483 static BOOL global_client_addr_done = False;
3485 void reset_globals_after_fork(void)
3487 global_client_name_done = False;
3488 global_client_addr_done = False;
3491 * Re-seed the random crypto generator, so all smbd's
3492 * started from the same parent won't generate the same
3496 unsigned char dummy;
3497 generate_random_buffer( &dummy, 1, True);
3501 /*******************************************************************
3502 return the DNS name of the client
3503 ******************************************************************/
3504 char *client_name(int fd)
3507 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3508 int length = sizeof(sa);
3509 static pstring name_buf;
3511 static int last_fd=-1;
3513 if (global_client_name_done && last_fd == fd)
3517 global_client_name_done = False;
3519 pstrcpy(name_buf,"UNKNOWN");
3525 if (getpeername(fd, &sa, &length) < 0) {
3526 DEBUG(0,("getpeername failed\n"));
3530 /* Look up the remote host name. */
3531 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3532 sizeof(sockin->sin_addr),
3534 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3535 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3537 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3538 if (!matchname(name_buf, sockin->sin_addr)) {
3539 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3540 pstrcpy(name_buf,"UNKNOWN");
3543 global_client_name_done = True;
3547 /*******************************************************************
3548 return the IP addr of the client as a string
3549 ******************************************************************/
3550 char *client_addr(int fd)
3553 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3554 int length = sizeof(sa);
3555 static fstring addr_buf;
3556 static int last_fd = -1;
3558 if (global_client_addr_done && fd == last_fd)
3562 global_client_addr_done = False;
3564 fstrcpy(addr_buf,"0.0.0.0");
3570 if (getpeername(fd, &sa, &length) < 0) {
3571 DEBUG(0,("getpeername failed\n"));
3575 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3577 global_client_addr_done = True;
3581 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3582 /******************************************************************
3583 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3584 Based on a fix from <Thomas.Hepper@icem.de>.
3585 *******************************************************************/
3587 static void strip_mount_options( pstring *str)
3592 while(*p && !isspace(*p))
3594 while(*p && isspace(*p))
3599 pstrcpy(tmp_str, p);
3600 pstrcpy(*str, tmp_str);
3605 /*******************************************************************
3606 Patch from jkf@soton.ac.uk
3607 Split Luke's automount_server into YP lookup and string splitter
3608 so can easily implement automount_path().
3609 As we may end up doing both, cache the last YP result.
3610 *******************************************************************/
3612 #ifdef WITH_NISPLUS_HOME
3613 static char *automount_lookup(char *user_name)
3615 static fstring last_key = "";
3616 static pstring last_value = "";
3618 char *nis_map = (char *)lp_nis_home_map_name();
3620 char nis_domain[NIS_MAXNAMELEN + 1];
3621 char buffer[NIS_MAXATTRVAL + 1];
3626 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3627 nis_domain[NIS_MAXNAMELEN] = '\0';
3629 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3631 if (strcmp(user_name, last_key))
3633 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3634 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3636 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3638 if (result->status != NIS_SUCCESS)
3640 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3641 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3645 object = result->objects.objects_val;
3646 if (object->zo_data.zo_type == ENTRY_OBJ)
3648 entry = &object->zo_data.objdata_u.en_data;
3649 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3650 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3652 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3653 string_sub(last_value, "&", user_name);
3654 fstrcpy(last_key, user_name);
3658 nis_freeresult(result);
3661 strip_mount_options(&last_value);
3663 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3666 #else /* WITH_NISPLUS_HOME */
3667 static char *automount_lookup(char *user_name)
3669 static fstring last_key = "";
3670 static pstring last_value = "";
3672 int nis_error; /* returned by yp all functions */
3673 char *nis_result; /* yp_match inits this */
3674 int nis_result_len; /* and set this */
3675 char *nis_domain; /* yp_get_default_domain inits this */
3676 char *nis_map = (char *)lp_nis_home_map_name();
3678 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3680 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3684 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3686 if (!strcmp(user_name, last_key))
3688 nis_result = last_value;
3689 nis_result_len = strlen(last_value);
3694 if ((nis_error = yp_match(nis_domain, nis_map,
3695 user_name, strlen(user_name),
3696 &nis_result, &nis_result_len)) != 0)
3698 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3699 yperr_string(nis_error), user_name, nis_map));
3701 if (!nis_error && nis_result_len >= sizeof(pstring))
3703 nis_result_len = sizeof(pstring)-1;
3705 fstrcpy(last_key, user_name);
3706 strncpy(last_value, nis_result, nis_result_len);
3707 last_value[nis_result_len] = '\0';
3710 strip_mount_options(&last_value);
3712 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3715 #endif /* WITH_NISPLUS_HOME */
3718 /*******************************************************************
3719 Patch from jkf@soton.ac.uk
3720 This is Luke's original function with the NIS lookup code
3721 moved out to a separate function.
3722 *******************************************************************/
3723 static char *automount_server(char *user_name)
3725 static pstring server_name;
3727 /* use the local machine name as the default */
3728 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3729 pstrcpy(server_name, local_machine);
3731 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3733 if (lp_nis_home_map())
3735 int home_server_len;
3736 char *automount_value = automount_lookup(user_name);
3737 home_server_len = strcspn(automount_value,":");
3738 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3739 if (home_server_len > sizeof(pstring))
3741 home_server_len = sizeof(pstring);
3743 strncpy(server_name, automount_value, home_server_len);
3744 server_name[home_server_len] = '\0';
3748 DEBUG(4,("Home server: %s\n", server_name));
3753 /*******************************************************************
3754 Patch from jkf@soton.ac.uk
3755 Added this to implement %p (NIS auto-map version of %H)
3756 *******************************************************************/
3757 static char *automount_path(char *user_name)
3759 static pstring server_path;
3761 /* use the passwd entry as the default */
3762 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3763 /* pstrcpy() copes with get_home_dir() returning NULL */
3764 pstrcpy(server_path, get_home_dir(user_name));
3766 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3768 if (lp_nis_home_map())
3770 char *home_path_start;
3771 char *automount_value = automount_lookup(user_name);
3772 home_path_start = strchr(automount_value,':');
3773 if (home_path_start != NULL)
3775 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3776 home_path_start?(home_path_start+1):""));
3777 pstrcpy(server_path, home_path_start+1);
3782 DEBUG(4,("Home server path: %s\n", server_path));
3788 /*******************************************************************
3789 sub strings with useful parameters
3790 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3791 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3792 ********************************************************************/
3793 void standard_sub_basic(char *str)
3797 struct passwd *pass;
3798 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3800 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3806 if ((pass = Get_Pwnam(username,False))!=NULL)
3808 string_sub(p,"%G",gidtoname(pass->pw_gid));
3816 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3817 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3818 case 'L' : string_sub(p,"%L", local_machine); break;
3819 case 'M' : string_sub(p,"%M", client_name(Client)); break;
3820 case 'R' : string_sub(p,"%R", remote_proto); break;
3821 case 'T' : string_sub(p,"%T", timestring()); break;
3822 case 'U' : string_sub(p,"%U", username); break;
3823 case 'a' : string_sub(p,"%a", remote_arch); break;
3826 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
3827 string_sub(p,"%d", pidstr);
3830 case 'h' : string_sub(p,"%h", myhostname); break;
3831 case 'm' : string_sub(p,"%m", remote_machine); break;
3832 case 'v' : string_sub(p,"%v", VERSION); break;
3833 case '$' : /* Expand environment variables */
3835 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3846 if ((q = strchr(p,')')) == NULL)
3848 DEBUG(0,("standard_sub_basic: Unterminated environment \
3849 variable [%s]\n", p));
3855 copylen = MIN((q-r),(sizeof(envname)-1));
3856 strncpy(envname,r,copylen);
3857 envname[copylen] = '\0';
3859 if ((envval = getenv(envname)) == NULL)
3861 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3867 copylen = MIN((q+1-p),(sizeof(envname)-1));
3868 strncpy(envname,p,copylen);
3869 envname[copylen] = '\0';
3870 string_sub(p,envname,envval);
3873 case '\0': p++; break; /* don't run off end if last character is % */
3874 default : p+=2; break;
3881 /****************************************************************************
3882 do some standard substitutions in a string
3883 ****************************************************************************/
3884 void standard_sub(connection_struct *conn,char *str)
3888 for (s=str; (p=strchr(s, '%'));s=p) {
3891 if ((home = get_home_dir(conn->user))) {
3892 string_sub(p,"%H",home);
3899 string_sub(p,"%P",conn->connectpath);
3904 lp_servicename(SNUM(conn)));
3909 gidtoname(conn->gid));
3912 string_sub(p,"%u",conn->user);
3915 /* Patch from jkf@soton.ac.uk Left the %N (NIS
3916 * server name) in standard_sub_basic as it is
3917 * a feature for logon servers, hence uses the
3918 * username. The %p (NIS server path) code is
3919 * here as it is used instead of the default
3920 * "path =" string in [homes] and so needs the
3921 * service name, not the username. */
3924 automount_path(lp_servicename(SNUM(conn))));
3928 break; /* don't run off the end of the string
3936 standard_sub_basic(str);
3941 /*******************************************************************
3942 are two IPs on the same subnet?
3943 ********************************************************************/
3944 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3946 uint32 net1,net2,nmask;
3948 nmask = ntohl(mask.s_addr);
3949 net1 = ntohl(ip1.s_addr);
3950 net2 = ntohl(ip2.s_addr);
3952 return((net1 & nmask) == (net2 & nmask));
3956 /*******************************************************************
3957 write a string in unicoode format
3958 ********************************************************************/
3959 int PutUniCode(char *dst,char *src)
3963 dst[ret++] = src[0];
3972 /****************************************************************************
3973 a wrapper for gethostbyname() that tries with all lower and all upper case
3974 if the initial name fails
3975 ****************************************************************************/
3976 struct hostent *Get_Hostbyname(char *name)
3978 char *name2 = strdup(name);
3979 struct hostent *ret;
3983 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3989 * This next test is redundent and causes some systems (with
3990 * broken isalnum() calls) problems.
3995 if (!isalnum(*name2))
4002 ret = sys_gethostbyname(name2);
4009 /* try with all lowercase */
4011 ret = sys_gethostbyname(name2);
4018 /* try with all uppercase */
4020 ret = sys_gethostbyname(name2);
4027 /* nothing works :-( */
4033 /****************************************************************************
4034 check if a process exists. Does this work on all unixes?
4035 ****************************************************************************/
4036 BOOL process_exists(int pid)
4038 return(kill(pid,0) == 0 || errno != ESRCH);
4042 /*******************************************************************
4043 turn a uid into a user name
4044 ********************************************************************/
4045 char *uidtoname(int uid)
4047 static char name[40];
4048 struct passwd *pass = getpwuid(uid);
4049 if (pass) return(pass->pw_name);
4050 slprintf(name, sizeof(name) - 1, "%d",uid);
4054 /*******************************************************************
4055 turn a gid into a group name
4056 ********************************************************************/
4057 char *gidtoname(int gid)
4059 static char name[40];
4060 struct group *grp = getgrgid(gid);
4061 if (grp) return(grp->gr_name);
4062 slprintf(name,sizeof(name) - 1, "%d",gid);
4066 /*******************************************************************
4067 something really nasty happened - panic!
4068 ********************************************************************/
4069 void smb_panic(char *why)
4071 char *cmd = lp_panic_action();
4075 DEBUG(0,("PANIC: %s\n", why));
4080 /*******************************************************************
4081 a readdir wrapper which just returns the file name
4082 ********************************************************************/
4083 char *readdirname(void *p)
4088 if (!p) return(NULL);
4090 ptr = (struct dirent *)readdir(p);
4091 if (!ptr) return(NULL);
4093 dname = ptr->d_name;
4096 if (telldir(p) < 0) return(NULL);
4099 #ifdef HAVE_BROKEN_READDIR
4100 /* using /usr/ucb/cc is BAD */
4106 memcpy(buf, dname, NAMLEN(ptr)+1);
4107 unix_to_dos(buf, True);
4114 /*******************************************************************
4115 Utility function used to decide if the last component
4116 of a path matches a (possibly wildcarded) entry in a namelist.
4117 ********************************************************************/
4119 BOOL is_in_path(char *name, name_compare_entry *namelist)
4121 pstring last_component;
4124 DEBUG(8, ("is_in_path: %s\n", name));
4126 /* if we have no list it's obviously not in the path */
4127 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4129 DEBUG(8,("is_in_path: no name list.\n"));
4133 /* Get the last component of the unix name. */
4134 p = strrchr(name, '/');
4135 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4136 last_component[sizeof(last_component)-1] = '\0';
4138 for(; namelist->name != NULL; namelist++)
4140 if(namelist->is_wild)
4143 * Look for a wildcard match. Use the old
4144 * 'unix style' mask match, rather than the
4147 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4149 DEBUG(8,("is_in_path: mask match succeeded\n"));
4155 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4156 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4158 DEBUG(8,("is_in_path: match succeeded\n"));
4163 DEBUG(8,("is_in_path: match not found\n"));
4168 /*******************************************************************
4169 Strip a '/' separated list into an array of
4170 name_compare_enties structures suitable for
4171 passing to is_in_path(). We do this for
4172 speed so we can pre-parse all the names in the list
4173 and don't do it for each call to is_in_path().
4174 namelist is modified here and is assumed to be
4175 a copy owned by the caller.
4176 We also check if the entry contains a wildcard to
4177 remove a potentially expensive call to mask_match
4179 ********************************************************************/
4181 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4184 char *nameptr = namelist;
4185 int num_entries = 0;
4188 (*ppname_array) = NULL;
4190 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4193 /* We need to make two passes over the string. The
4194 first to count the number of elements, the second
4199 if ( *nameptr == '/' )
4201 /* cope with multiple (useless) /s) */
4205 /* find the next / */
4206 name_end = strchr(nameptr, '/');
4208 /* oops - the last check for a / didn't find one. */
4209 if (name_end == NULL)
4212 /* next segment please */
4213 nameptr = name_end + 1;
4217 if(num_entries == 0)
4220 if(( (*ppname_array) = (name_compare_entry *)malloc(
4221 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4223 DEBUG(0,("set_namearray: malloc fail\n"));
4227 /* Now copy out the names */
4232 if ( *nameptr == '/' )
4234 /* cope with multiple (useless) /s) */
4238 /* find the next / */
4239 if ((name_end = strchr(nameptr, '/')) != NULL)
4244 /* oops - the last check for a / didn't find one. */
4245 if(name_end == NULL)
4248 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4249 (strchr( nameptr, '*')!=NULL));
4250 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4252 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4256 /* next segment please */
4257 nameptr = name_end + 1;
4261 (*ppname_array)[i].name = NULL;
4266 /****************************************************************************
4267 routine to free a namearray.
4268 ****************************************************************************/
4270 void free_namearray(name_compare_entry *name_array)
4275 if(name_array->name != NULL)
4276 free(name_array->name);
4278 free((char *)name_array);
4281 /****************************************************************************
4282 routine to do file locking
4283 ****************************************************************************/
4284 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
4287 SMB_STRUCT_FLOCK lock;
4290 if(lp_ole_locking_compat()) {
4291 SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
4292 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
4294 /* make sure the count is reasonable, we might kill the lockd otherwise */
4297 /* the offset is often strange - remove 2 of its bits if either of
4298 the top two bits are set. Shift the top ones by two bits. This
4299 still allows OLE2 apps to operate, but should stop lockd from
4301 if ((offset & mask) != 0)
4302 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
4304 SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
4305 SMB_OFF_T neg_mask = ~mask;
4307 /* interpret negative counts as large numbers */
4311 /* no negative offsets */
4315 /* count + offset must be in range */
4316 while ((offset < 0 || (offset + count < 0)) && mask)
4319 mask = ((mask >> 1) & neg_mask);
4323 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
4326 lock.l_whence = SEEK_SET;
4327 lock.l_start = offset;
4333 ret = fcntl(fd,op,&lock);
4338 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
4339 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
4340 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
4342 /* 32 bit NFS file system, retry with smaller offset */
4344 lock.l_len = count & 0xffffffff;
4345 ret = fcntl(fd,op,&lock);
4349 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4352 if (op == SMB_F_GETLK)
4355 (lock.l_type != F_UNLCK) &&
4356 (lock.l_pid != 0) &&
4357 (lock.l_pid != getpid()))
4359 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4363 /* it must be not locked or locked by me */
4367 /* a lock set or unset */
4370 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
4371 (double)offset,(double)count,op,type,strerror(errno)));
4373 /* perhaps it doesn't support this sort of locking?? */
4374 if (errno == EINVAL)
4376 DEBUG(3,("locking not supported? returning True\n"));
4383 /* everything went OK */
4384 DEBUG(8,("Lock call successful\n"));
4392 /*******************************************************************
4393 is the name specified one of my netbios names
4394 returns true is it is equal, false otherwise
4395 ********************************************************************/
4396 BOOL is_myname(char *s)
4401 for (n=0; my_netbios_names[n]; n++) {
4402 if (strequal(my_netbios_names[n], s))
4405 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4409 /*******************************************************************
4410 set the horrid remote_arch string based on an enum.
4411 ********************************************************************/
4412 void set_remote_arch(enum remote_arch_types type)
4418 fstrcpy(remote_arch, "WfWg");
4421 fstrcpy(remote_arch, "OS2");
4424 fstrcpy(remote_arch, "Win95");
4427 fstrcpy(remote_arch, "WinNT");
4430 fstrcpy(remote_arch,"Samba");
4433 ra_type = RA_UNKNOWN;
4434 fstrcpy(remote_arch, "UNKNOWN");
4439 /*******************************************************************
4440 Get the remote_arch type.
4441 ********************************************************************/
4442 enum remote_arch_types get_remote_arch(void)
4448 /*******************************************************************
4449 skip past some unicode strings in a buffer
4450 ********************************************************************/
4451 char *skip_unicode_string(char *buf,int n)
4462 /*******************************************************************
4463 Return a ascii version of a unicode string
4464 Hack alert: uses fixed buffer(s) and only handles ascii strings
4465 ********************************************************************/
4467 char *unistrn2(uint16 *buf, int len)
4469 static char lbufs[8][MAXUNI];
4471 char *lbuf = lbufs[nexti];
4474 nexti = (nexti+1)%8;
4476 DEBUG(10, ("unistrn2: "));
4478 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4480 DEBUG(10, ("%4x ", *buf));
4490 /*******************************************************************
4491 Return a ascii version of a unicode string
4492 Hack alert: uses fixed buffer(s) and only handles ascii strings
4493 ********************************************************************/
4495 char *unistr2(uint16 *buf)
4497 static char lbufs[8][MAXUNI];
4499 char *lbuf = lbufs[nexti];
4502 nexti = (nexti+1)%8;
4504 DEBUG(10, ("unistr2: "));
4506 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4508 DEBUG(10, ("%4x ", *buf));
4518 /*******************************************************************
4519 create a null-terminated unicode string from a null-terminated ascii string.
4520 return number of unicode chars copied, excluding the null character.
4522 only handles ascii strings
4523 ********************************************************************/
4525 int struni2(uint16 *p, char *buf)
4529 if (p == NULL) return 0;
4531 DEBUG(10, ("struni2: "));
4535 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4537 DEBUG(10, ("%2x ", *buf));
4549 /*******************************************************************
4550 Return a ascii version of a unicode string
4551 Hack alert: uses fixed buffer(s) and only handles ascii strings
4552 ********************************************************************/
4554 char *unistr(char *buf)
4556 static char lbufs[8][MAXUNI];
4558 char *lbuf = lbufs[nexti];
4561 nexti = (nexti+1)%8;
4563 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4572 /*******************************************************************
4573 strcpy for unicode strings. returns length (in num of wide chars)
4574 ********************************************************************/
4575 int unistrcpy(char *dst, char *src)
4591 /*******************************************************************
4592 safe string copy into a known length string. maxlength does not
4593 include the terminating zero.
4594 ********************************************************************/
4595 char *safe_strcpy(char *dest, char *src, int maxlength)
4600 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4611 if (len > maxlength) {
4612 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4613 len-maxlength, src));
4617 memcpy(dest, src, len);
4622 /*******************************************************************
4623 safe string cat into a string. maxlength does not
4624 include the terminating zero.
4625 ********************************************************************/
4626 char *safe_strcat(char *dest, char *src, int maxlength)
4628 int src_len, dest_len;
4631 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4639 src_len = strlen(src);
4640 dest_len = strlen(dest);
4642 if (src_len + dest_len > maxlength) {
4643 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4644 src_len + dest_len - maxlength, src));
4645 src_len = maxlength - dest_len;
4648 memcpy(&dest[dest_len], src, src_len);
4649 dest[dest_len + src_len] = 0;
4653 /*******************************************************************
4654 align a pointer to a multiple of 2 bytes
4655 ********************************************************************/
4656 char *align2(char *q, char *base)
4665 void print_asc(int level, unsigned char *buf,int len)
4669 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4672 void dump_data(int level,char *buf1,int len)
4674 unsigned char *buf = (unsigned char *)buf1;
4678 DEBUG(level,("[%03X] ",i));
4680 DEBUG(level,("%02X ",(int)buf[i]));
4682 if (i%8 == 0) DEBUG(level,(" "));
4684 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4685 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4686 if (i<len) DEBUG(level,("[%03X] ",i));
4694 if (n>8) DEBUG(level,(" "));
4695 while (n--) DEBUG(level,(" "));
4698 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4700 if (n>0) print_asc(level,&buf[i-n],n);
4701 DEBUG(level,("\n"));
4705 char *tab_depth(int depth)
4707 static pstring spaces;
4708 memset(spaces, ' ', depth * 4);
4709 spaces[depth * 4] = 0;
4713 /*****************************************************************
4714 Convert a SID to an ascii string.
4715 *****************************************************************/
4717 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
4721 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4722 uint32 ia = (sid->id_auth[5]) +
4723 (sid->id_auth[4] << 8 ) +
4724 (sid->id_auth[3] << 16) +
4725 (sid->id_auth[2] << 24);
4727 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4729 for (i = 0; i < sid->num_auths; i++)
4731 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4732 pstrcat(sidstr_out, subauth);
4735 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
4739 /*****************************************************************
4740 Convert a string to a SID. Returns True on success, False on fail.
4741 *****************************************************************/
4743 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
4747 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4750 memset((char *)sidout, '\0', sizeof(DOM_SID));
4752 if(StrnCaseCmp( sidstr, "S-", 2)) {
4753 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
4758 if(!next_token(&p, tok, "-", sizeof(tok))) {
4759 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4763 /* Get the revision number. */
4764 sidout->sid_rev_num = atoi(tok);
4766 if(!next_token(&p, tok, "-", sizeof(tok))) {
4767 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4771 /* identauth in decimal should be < 2^32 */
4774 /* NOTE - the ia value is in big-endian format. */
4775 sidout->id_auth[0] = 0;
4776 sidout->id_auth[1] = 0;
4777 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
4778 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
4779 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
4780 sidout->id_auth[5] = (ia & 0x000000ff);
4782 sidout->num_auths = 0;
4784 while(next_token(&p, tok, "-", sizeof(tok)) &&
4785 sidout->num_auths < MAXSUBAUTHS) {
4787 * NOTE - the subauths are in native machine-endian format. They
4788 * are converted to little-endian when linearized onto the wire.
4790 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
4793 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
4798 /*****************************************************************************
4799 * Provide a checksum on a string
4801 * Input: s - the nul-terminated character string for which the checksum
4802 * will be calculated.
4804 * Output: The checksum value calculated for s.
4806 * ****************************************************************************
4808 int str_checksum(char *s)
4816 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
4821 } /* str_checksum */
4825 /*****************************************************************
4826 zero a memory area then free it. Used to catch bugs faster
4827 *****************************************************************/
4828 void zero_free(void *p, size_t size)