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 ****************************************************************************/
350 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
354 if (group == current_gid) return(True);
356 for (i=0;i<ngroups;i++)
357 if (group == groups[i])
363 /****************************************************************************
364 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
365 ****************************************************************************/
366 char *StrCpy(char *dest,char *src)
370 /* I don't want to get lazy with these ... */
371 SMB_ASSERT(dest && src);
373 if (!dest) return(NULL);
378 while ((*d++ = *src++)) ;
382 /****************************************************************************
383 line strncpy but always null terminates. Make sure there is room!
384 ****************************************************************************/
385 char *StrnCpy(char *dest,char *src,int n)
388 if (!dest) return(NULL);
393 while (n-- && (*d++ = *src++)) ;
399 /*******************************************************************
400 copy an IP address from one buffer to another
401 ********************************************************************/
402 void putip(void *dest,void *src)
408 #define TRUNCATE_NETBIOS_NAME 1
410 /*******************************************************************
411 convert, possibly using a stupid microsoft-ism which has destroyed
412 the transport independence of netbios (for CIFS vendors that usually
413 use the Win95-type methods, not for NT to NT communication, which uses
414 DCE/RPC and therefore full-length unicode strings...) a dns name into
417 the netbios name (NOT necessarily null-terminated) is truncated to 15
420 ******************************************************************/
421 char *dns_to_netbios_name(char *dns_name)
423 static char netbios_name[16];
425 StrnCpy(netbios_name, dns_name, 15);
426 netbios_name[15] = 0;
428 #ifdef TRUNCATE_NETBIOS_NAME
429 /* ok. this is because of a stupid microsoft-ism. if the called host
430 name contains a '.', microsoft clients expect you to truncate the
431 netbios name up to and including the '.' this even applies, by
432 mistake, to workgroup (domain) names, which is _really_ daft.
434 for (i = 15; i >= 0; i--)
436 if (netbios_name[i] == '.')
442 #endif /* TRUNCATE_NETBIOS_NAME */
448 /****************************************************************************
449 interpret the weird netbios "name". Return the name type
450 ****************************************************************************/
451 static int name_interpret(char *in,char *out)
454 int len = (*in++) / 2;
458 if (len > 30 || len<1) return(0);
462 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
466 *out = ((in[0]-'A')<<4) + (in[1]-'A');
474 /* Handle any scope names */
477 *out++ = '.'; /* Scope names are separated by periods */
478 len = *(unsigned char *)in++;
479 StrnCpy(out, in, len);
488 /****************************************************************************
489 mangle a name into netbios format
491 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
492 ****************************************************************************/
493 int name_mangle( char *In, char *Out, char name_type )
501 /* Safely copy the input string, In, into buf[]. */
502 (void)memset( buf, 0, 20 );
503 if (strcmp(In,"*") == 0)
506 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
508 /* Place the length of the first field into the output buffer. */
512 /* Now convert the name to the rfc1001/1002 format. */
513 for( i = 0; i < 16; i++ )
515 c = toupper( buf[i] );
516 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
517 p[(i*2)+1] = (c & 0x000F) + 'A';
522 /* Add the scope string. */
523 for( i = 0, len = 0; NULL != scope; i++, len++ )
531 return( name_len(Out) );
543 return( name_len(Out) );
546 /*******************************************************************
547 check if a file exists
548 ********************************************************************/
549 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
552 if (!sbuf) sbuf = &st;
554 if (dos_stat(fname,sbuf) != 0)
557 return(S_ISREG(sbuf->st_mode));
560 /*******************************************************************
561 check a files mod time
562 ********************************************************************/
563 time_t file_modtime(char *fname)
567 if (dos_stat(fname,&st) != 0)
573 /*******************************************************************
574 check if a directory exists
575 ********************************************************************/
576 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
583 if (dos_stat(dname,st) != 0)
586 ret = S_ISDIR(st->st_mode);
592 /*******************************************************************
593 returns the size in bytes of the named file
594 ********************************************************************/
595 SMB_OFF_T file_size(char *file_name)
599 dos_stat(file_name,&buf);
603 /*******************************************************************
604 return a string representing an attribute for a file
605 ********************************************************************/
606 char *attrib_string(int mode)
608 static fstring attrstr;
612 if (mode & aVOLID) fstrcat(attrstr,"V");
613 if (mode & aDIR) fstrcat(attrstr,"D");
614 if (mode & aARCH) fstrcat(attrstr,"A");
615 if (mode & aHIDDEN) fstrcat(attrstr,"H");
616 if (mode & aSYSTEM) fstrcat(attrstr,"S");
617 if (mode & aRONLY) fstrcat(attrstr,"R");
623 /*******************************************************************
624 case insensitive string compararison
625 ********************************************************************/
626 int StrCaseCmp(char *s, char *t)
628 /* compare until we run out of string, either t or s, or find a difference */
629 /* We *must* use toupper rather than tolower here due to the
630 asynchronous upper to lower mapping.
632 #if !defined(KANJI_WIN95_COMPATIBILITY)
634 * For completeness we should put in equivalent code for code pages
635 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
636 * doubt anyone wants Samba to behave differently from Win95 and WinNT
637 * here. They both treat full width ascii characters as case senstive
638 * filenames (ie. they don't do the work we do here).
642 if(lp_client_code_page() == KANJI_CODEPAGE)
644 /* Win95 treats full width ascii characters as case sensitive. */
649 return toupper (*s) - toupper (*t);
650 else if (is_sj_alph (*s) && is_sj_alph (*t))
652 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
658 else if (is_shift_jis (*s) && is_shift_jis (*t))
660 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
663 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
669 else if (is_shift_jis (*s))
671 else if (is_shift_jis (*t))
675 diff = toupper (*s) - toupper (*t);
684 #endif /* KANJI_WIN95_COMPATIBILITY */
686 while (*s && *t && toupper(*s) == toupper(*t))
692 return(toupper(*s) - toupper(*t));
696 /*******************************************************************
697 case insensitive string compararison, length limited
698 ********************************************************************/
699 int StrnCaseCmp(char *s, char *t, int n)
701 /* compare until we run out of string, either t or s, or chars */
702 /* We *must* use toupper rather than tolower here due to the
703 asynchronous upper to lower mapping.
705 #if !defined(KANJI_WIN95_COMPATIBILITY)
707 * For completeness we should put in equivalent code for code pages
708 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
709 * doubt anyone wants Samba to behave differently from Win95 and WinNT
710 * here. They both treat full width ascii characters as case senstive
711 * filenames (ie. they don't do the work we do here).
715 if(lp_client_code_page() == KANJI_CODEPAGE)
717 /* Win95 treats full width ascii characters as case sensitive. */
722 return toupper (*s) - toupper (*t);
723 else if (is_sj_alph (*s) && is_sj_alph (*t))
725 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
732 else if (is_shift_jis (*s) && is_shift_jis (*t))
734 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
737 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
744 else if (is_shift_jis (*s))
746 else if (is_shift_jis (*t))
750 diff = toupper (*s) - toupper (*t);
761 #endif /* KANJI_WIN95_COMPATIBILITY */
763 while (n && *s && *t && toupper(*s) == toupper(*t))
770 /* not run out of chars - strings are different lengths */
772 return(toupper(*s) - toupper(*t));
774 /* identical up to where we run out of chars,
775 and strings are same length */
780 /*******************************************************************
782 ********************************************************************/
783 BOOL strequal(char *s1, char *s2)
785 if (s1 == s2) return(True);
786 if (!s1 || !s2) return(False);
788 return(StrCaseCmp(s1,s2)==0);
791 /*******************************************************************
792 compare 2 strings up to and including the nth char.
793 ******************************************************************/
794 BOOL strnequal(char *s1,char *s2,int n)
796 if (s1 == s2) return(True);
797 if (!s1 || !s2 || !n) return(False);
799 return(StrnCaseCmp(s1,s2,n)==0);
802 /*******************************************************************
803 compare 2 strings (case sensitive)
804 ********************************************************************/
805 BOOL strcsequal(char *s1,char *s2)
807 if (s1 == s2) return(True);
808 if (!s1 || !s2) return(False);
810 return(strcmp(s1,s2)==0);
814 /*******************************************************************
815 convert a string to lower case
816 ********************************************************************/
817 void strlower(char *s)
821 #if !defined(KANJI_WIN95_COMPATIBILITY)
823 * For completeness we should put in equivalent code for code pages
824 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
825 * doubt anyone wants Samba to behave differently from Win95 and WinNT
826 * here. They both treat full width ascii characters as case senstive
827 * filenames (ie. they don't do the work we do here).
831 if(lp_client_code_page() == KANJI_CODEPAGE)
833 /* Win95 treats full width ascii characters as case sensitive. */
834 if (is_shift_jis (*s))
836 if (is_sj_upper (s[0], s[1]))
837 s[1] = sj_tolower2 (s[1]);
840 else if (is_kana (*s))
852 #endif /* KANJI_WIN95_COMPATIBILITY */
854 int skip = skip_multibyte_char( *s );
867 /*******************************************************************
868 convert a string to upper case
869 ********************************************************************/
870 void strupper(char *s)
874 #if !defined(KANJI_WIN95_COMPATIBILITY)
876 * For completeness we should put in equivalent code for code pages
877 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
878 * doubt anyone wants Samba to behave differently from Win95 and WinNT
879 * here. They both treat full width ascii characters as case senstive
880 * filenames (ie. they don't do the work we do here).
884 if(lp_client_code_page() == KANJI_CODEPAGE)
886 /* Win95 treats full width ascii characters as case sensitive. */
887 if (is_shift_jis (*s))
889 if (is_sj_lower (s[0], s[1]))
890 s[1] = sj_toupper2 (s[1]);
893 else if (is_kana (*s))
905 #endif /* KANJI_WIN95_COMPATIBILITY */
907 int skip = skip_multibyte_char( *s );
920 /*******************************************************************
921 convert a string to "normal" form
922 ********************************************************************/
923 void strnorm(char *s)
925 if (case_default == CASE_UPPER)
931 /*******************************************************************
932 check if a string is in "normal" case
933 ********************************************************************/
934 BOOL strisnormal(char *s)
936 if (case_default == CASE_UPPER)
937 return(!strhaslower(s));
939 return(!strhasupper(s));
943 /****************************************************************************
945 ****************************************************************************/
946 void string_replace(char *s,char oldc,char newc)
951 skip = skip_multibyte_char( *s );
963 /****************************************************************************
964 make a file into unix format
965 ****************************************************************************/
966 void unix_format(char *fname)
968 string_replace(fname,'\\','/');
971 /****************************************************************************
972 make a file into dos format
973 ****************************************************************************/
974 void dos_format(char *fname)
976 string_replace(fname,'/','\\');
979 /*******************************************************************
980 show a smb message structure
981 ********************************************************************/
982 void show_msg(char *buf)
987 if (DEBUGLEVEL < 5) return;
989 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
991 (int)CVAL(buf,smb_com),
992 (int)CVAL(buf,smb_rcls),
993 (int)CVAL(buf,smb_reh),
994 (int)SVAL(buf,smb_err),
995 (int)CVAL(buf,smb_flg),
996 (int)SVAL(buf,smb_flg2)));
997 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
998 (int)SVAL(buf,smb_tid),
999 (int)SVAL(buf,smb_pid),
1000 (int)SVAL(buf,smb_uid),
1001 (int)SVAL(buf,smb_mid),
1002 (int)CVAL(buf,smb_wct)));
1004 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1006 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1007 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1010 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1012 DEBUG(5,("smb_bcc=%d\n",bcc));
1014 if (DEBUGLEVEL < 10) return;
1016 if (DEBUGLEVEL < 50)
1018 bcc = MIN(bcc, 512);
1021 dump_data(10, smb_buf(buf), bcc);
1023 /*******************************************************************
1024 return the length of an smb packet
1025 ********************************************************************/
1026 int smb_len(char *buf)
1028 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1031 /*******************************************************************
1032 set the length of an smb packet
1033 ********************************************************************/
1034 void _smb_setlen(char *buf,int len)
1037 buf[1] = (len&0x10000)>>16;
1038 buf[2] = (len&0xFF00)>>8;
1042 /*******************************************************************
1043 set the length and marker of an smb packet
1044 ********************************************************************/
1045 void smb_setlen(char *buf,int len)
1047 _smb_setlen(buf,len);
1055 /*******************************************************************
1056 setup the word count and byte count for a smb message
1057 ********************************************************************/
1058 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1061 bzero(buf + smb_size,num_words*2 + num_bytes);
1062 CVAL(buf,smb_wct) = num_words;
1063 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1064 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1065 return (smb_size + num_words*2 + num_bytes);
1068 /*******************************************************************
1069 return the number of smb words
1070 ********************************************************************/
1071 static int smb_numwords(char *buf)
1073 return (CVAL(buf,smb_wct));
1076 /*******************************************************************
1077 return the size of the smb_buf region of a message
1078 ********************************************************************/
1079 int smb_buflen(char *buf)
1081 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1084 /*******************************************************************
1085 return a pointer to the smb_buf data area
1086 ********************************************************************/
1087 static int smb_buf_ofs(char *buf)
1089 return (smb_size + CVAL(buf,smb_wct)*2);
1092 /*******************************************************************
1093 return a pointer to the smb_buf data area
1094 ********************************************************************/
1095 char *smb_buf(char *buf)
1097 return (buf + smb_buf_ofs(buf));
1100 /*******************************************************************
1101 return the SMB offset into an SMB buffer
1102 ********************************************************************/
1103 int smb_offset(char *p,char *buf)
1105 return(PTR_DIFF(p,buf+4) + chain_size);
1109 /*******************************************************************
1110 skip past some strings in a buffer
1111 ********************************************************************/
1112 char *skip_string(char *buf,int n)
1115 buf += strlen(buf) + 1;
1119 /*******************************************************************
1120 trim the specified elements off the front and back of a string
1121 ********************************************************************/
1122 BOOL trim_string(char *s,char *front,char *back)
1125 size_t front_len = (front && *front) ? strlen(front) : 0;
1126 size_t back_len = (back && *back) ? strlen(back) : 0;
1129 while (front_len && strncmp(s, front, front_len) == 0)
1135 if (!(*p = p[front_len]))
1142 while (back_len && s_len >= back_len &&
1143 (strncmp(s + s_len - back_len, back, back_len)==0))
1146 s[s_len - back_len] = 0;
1153 /*******************************************************************
1154 reduce a file name, removing .. elements.
1155 ********************************************************************/
1156 void dos_clean_name(char *s)
1160 DEBUG(3,("dos_clean_name [%s]\n",s));
1162 /* remove any double slashes */
1163 string_sub(s, "\\\\", "\\");
1165 while ((p = strstr(s,"\\..\\")) != NULL)
1172 if ((p=strrchr(s,'\\')) != NULL)
1179 trim_string(s,NULL,"\\..");
1181 string_sub(s, "\\.\\", "\\");
1184 /*******************************************************************
1185 reduce a file name, removing .. elements.
1186 ********************************************************************/
1187 void unix_clean_name(char *s)
1191 DEBUG(3,("unix_clean_name [%s]\n",s));
1193 /* remove any double slashes */
1194 string_sub(s, "//","/");
1196 /* Remove leading ./ characters */
1197 if(strncmp(s, "./", 2) == 0) {
1198 trim_string(s, "./", NULL);
1203 while ((p = strstr(s,"/../")) != NULL)
1210 if ((p=strrchr(s,'/')) != NULL)
1217 trim_string(s,NULL,"/..");
1221 /*******************************************************************
1222 a wrapper for the normal chdir() function
1223 ********************************************************************/
1224 int ChDir(char *path)
1227 static pstring LastDir="";
1229 if (strcsequal(path,".")) return(0);
1231 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1232 DEBUG(3,("chdir to %s\n",path));
1233 res = dos_chdir(path);
1235 pstrcpy(LastDir,path);
1239 /* number of list structures for a caching GetWd function. */
1240 #define MAX_GETWDCACHE (50)
1244 SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
1245 SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
1246 char *text; /* The pathname in DOS format. */
1248 } ino_list[MAX_GETWDCACHE];
1250 BOOL use_getwd_cache=True;
1252 /*******************************************************************
1253 return the absolute current directory path - given a UNIX pathname.
1254 Note that this path is returned in DOS format, not UNIX
1256 ********************************************************************/
1257 char *GetWd(char *str)
1260 static BOOL getwd_cache_init = False;
1261 SMB_STRUCT_STAT st, st2;
1266 if (!use_getwd_cache)
1267 return(dos_getwd(str));
1269 /* init the cache */
1270 if (!getwd_cache_init)
1272 getwd_cache_init = True;
1273 for (i=0;i<MAX_GETWDCACHE;i++)
1275 string_init(&ino_list[i].text,"");
1276 ino_list[i].valid = False;
1280 /* Get the inode of the current directory, if this doesn't work we're
1283 if (dos_stat(".",&st) == -1)
1285 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1286 return(dos_getwd(str));
1290 for (i=0; i<MAX_GETWDCACHE; i++)
1291 if (ino_list[i].valid)
1294 /* If we have found an entry with a matching inode and dev number
1295 then find the inode number for the directory in the cached string.
1296 If this agrees with that returned by the stat for the current
1297 directory then all is o.k. (but make sure it is a directory all
1300 if (st.st_ino == ino_list[i].inode &&
1301 st.st_dev == ino_list[i].dev)
1303 if (dos_stat(ino_list[i].text,&st2) == 0)
1305 if (st.st_ino == st2.st_ino &&
1306 st.st_dev == st2.st_dev &&
1307 (st2.st_mode & S_IFMT) == S_IFDIR)
1309 pstrcpy (str, ino_list[i].text);
1311 /* promote it for future use */
1312 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1317 /* If the inode is different then something's changed,
1318 scrub the entry and start from scratch. */
1319 ino_list[i].valid = False;
1326 /* We don't have the information to hand so rely on traditional methods.
1327 The very slow getcwd, which spawns a process on some systems, or the
1328 not quite so bad getwd. */
1332 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1338 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1340 /* add it to the cache */
1341 i = MAX_GETWDCACHE - 1;
1342 string_set(&ino_list[i].text,s);
1343 ino_list[i].dev = st.st_dev;
1344 ino_list[i].inode = st.st_ino;
1345 ino_list[i].valid = True;
1347 /* put it at the top of the list */
1348 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1355 /*******************************************************************
1356 reduce a file name, removing .. elements and checking that
1357 it is below dir in the heirachy. This uses GetWd() and so must be run
1358 on the system that has the referenced file system.
1360 widelinks are allowed if widelinks is true
1361 ********************************************************************/
1362 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1364 #ifndef REDUCE_PATHS
1372 BOOL relative = (*s != '/');
1374 *dir2 = *wd = *base_name = *newname = 0;
1379 /* can't have a leading .. */
1380 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1382 DEBUG(3,("Illegal file name? (%s)\n",s));
1392 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1394 /* remove any double slashes */
1395 string_sub(s,"//","/");
1397 pstrcpy(base_name,s);
1398 p = strrchr(base_name,'/');
1405 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1409 if (ChDir(dir) != 0)
1411 DEBUG(0,("couldn't chdir to %s\n",dir));
1417 DEBUG(0,("couldn't getwd for %s\n",dir));
1423 if (p && (p != base_name))
1426 if (strcmp(p+1,".")==0)
1428 if (strcmp(p+1,"..")==0)
1432 if (ChDir(base_name) != 0)
1435 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1439 if (!GetWd(newname))
1442 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1446 if (p && (p != base_name))
1448 pstrcat(newname,"/");
1449 pstrcat(newname,p+1);
1453 int l = strlen(dir2);
1454 if (dir2[l-1] == '/')
1457 if (strncmp(newname,dir2,l) != 0)
1460 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1466 if (newname[l] == '/')
1467 pstrcpy(s,newname + l + 1);
1469 pstrcpy(s,newname+l);
1480 DEBUG(3,("reduced to %s\n",s));
1485 /****************************************************************************
1487 ****************************************************************************/
1488 static void expand_one(char *Mask,int len)
1491 while ((p1 = strchr(Mask,'*')) != NULL)
1493 int lfill = (len+1) - strlen(Mask);
1494 int l1= (p1 - Mask);
1497 memset(tmp+l1,'?',lfill);
1498 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1503 /****************************************************************************
1504 parse out a directory name from a path name. Assumes dos style filenames.
1505 ****************************************************************************/
1506 static char *dirname_dos(char *path,char *buf)
1508 char *p = strrchr(path,'\\');
1523 /****************************************************************************
1524 expand a wildcard expression, replacing *s with ?s
1525 ****************************************************************************/
1526 void expand_mask(char *Mask,BOOL doext)
1531 BOOL hasdot = False;
1533 BOOL absolute = (*Mask == '\\');
1535 *mbeg = *mext = *dirpart = *filepart = 0;
1537 /* parse the directory and filename */
1538 if (strchr(Mask,'\\'))
1539 dirname_dos(Mask,dirpart);
1541 filename_dos(Mask,filepart);
1543 pstrcpy(mbeg,filepart);
1544 if ((p1 = strchr(mbeg,'.')) != NULL)
1554 if (strlen(mbeg) > 8)
1556 pstrcpy(mext,mbeg + 8);
1562 pstrcpy(mbeg,"????????");
1563 if ((*mext == 0) && doext && !hasdot)
1564 pstrcpy(mext,"???");
1566 if (strequal(mbeg,"*") && *mext==0)
1574 pstrcpy(Mask,dirpart);
1575 if (*dirpart || absolute) pstrcat(Mask,"\\");
1580 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1584 /****************************************************************************
1585 does a string have any uppercase chars in it?
1586 ****************************************************************************/
1587 BOOL strhasupper(char *s)
1591 #if !defined(KANJI_WIN95_COMPATIBILITY)
1593 * For completeness we should put in equivalent code for code pages
1594 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1595 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1596 * here. They both treat full width ascii characters as case senstive
1597 * filenames (ie. they don't do the work we do here).
1601 if(lp_client_code_page() == KANJI_CODEPAGE)
1603 /* Win95 treats full width ascii characters as case sensitive. */
1604 if (is_shift_jis (*s))
1606 else if (is_kana (*s))
1616 #endif /* KANJI_WIN95_COMPATIBILITY */
1618 int skip = skip_multibyte_char( *s );
1631 /****************************************************************************
1632 does a string have any lowercase chars in it?
1633 ****************************************************************************/
1634 BOOL strhaslower(char *s)
1638 #if !defined(KANJI_WIN95_COMPATIBILITY)
1640 * For completeness we should put in equivalent code for code pages
1641 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1642 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1643 * here. They both treat full width ascii characters as case senstive
1644 * filenames (ie. they don't do the work we do here).
1648 if(lp_client_code_page() == KANJI_CODEPAGE)
1650 /* Win95 treats full width ascii characters as case sensitive. */
1651 if (is_shift_jis (*s))
1653 if (is_sj_upper (s[0], s[1]))
1655 if (is_sj_lower (s[0], s[1]))
1659 else if (is_kana (*s))
1671 #endif /* KANJI_WIN95_COMPATIBILITY */
1673 int skip = skip_multibyte_char( *s );
1686 /****************************************************************************
1687 find the number of chars in a string
1688 ****************************************************************************/
1689 int count_chars(char *s,char c)
1693 #if !defined(KANJI_WIN95_COMPATIBILITY)
1695 * For completeness we should put in equivalent code for code pages
1696 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1697 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1698 * here. They both treat full width ascii characters as case senstive
1699 * filenames (ie. they don't do the work we do here).
1703 if(lp_client_code_page() == KANJI_CODEPAGE)
1705 /* Win95 treats full width ascii characters as case sensitive. */
1708 if (is_shift_jis (*s))
1719 #endif /* KANJI_WIN95_COMPATIBILITY */
1723 int skip = skip_multibyte_char( *s );
1737 /****************************************************************************
1739 ****************************************************************************/
1740 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
1745 pstrcpy(mask2,mask);
1747 if ((mode & aDIR) != 0)
1750 memset(buf+1,' ',11);
1751 if ((p = strchr(mask2,'.')) != NULL)
1754 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1755 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1759 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1761 bzero(buf+21,DIR_STRUCT_SIZE-21);
1762 CVAL(buf,21) = mode;
1763 put_dos_date(buf,22,date);
1764 SSVAL(buf,26,size & 0xFFFF);
1765 SSVAL(buf,28,(size >> 16)&0xFFFF);
1766 StrnCpy(buf+30,fname,12);
1767 if (!case_sensitive)
1769 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1773 /*******************************************************************
1774 close the low 3 fd's and open dev/null in their place
1775 ********************************************************************/
1776 void close_low_fds(void)
1780 close(0); close(1); close(2);
1781 /* try and use up these file descriptors, so silly
1782 library routines writing to stdout etc won't cause havoc */
1784 fd = open("/dev/null",O_RDWR,0);
1785 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1787 DEBUG(0,("Can't open /dev/null\n"));
1791 DEBUG(0,("Didn't get file descriptor %d\n",i));
1797 /****************************************************************************
1798 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1800 if SYSV use O_NDELAY
1802 ****************************************************************************/
1803 static int set_blocking(int fd, BOOL set)
1807 #define FLAG_TO_SET O_NONBLOCK
1810 #define FLAG_TO_SET O_NDELAY
1812 #define FLAG_TO_SET FNDELAY
1816 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1818 if(set) /* Turn blocking on - ie. clear nonblock flag */
1819 val &= ~FLAG_TO_SET;
1822 return fcntl( fd, F_SETFL, val);
1827 /****************************************************************************
1829 ****************************************************************************/
1830 ssize_t write_socket(int fd,char *buf,size_t len)
1836 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1837 ret = write_data(fd,buf,len);
1839 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1841 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
1842 len, fd, strerror(errno) ));
1847 /****************************************************************************
1849 ****************************************************************************/
1850 ssize_t read_udp_socket(int fd,char *buf,size_t len)
1853 struct sockaddr_in sock;
1856 socklen = sizeof(sock);
1857 bzero((char *)&sock,socklen);
1858 bzero((char *)&lastip,sizeof(lastip));
1859 ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1861 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1865 lastip = sock.sin_addr;
1866 lastport = ntohs(sock.sin_port);
1868 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1869 inet_ntoa(lastip), lastport, ret));
1874 /****************************************************************************
1875 read data from a device with a timout in msec.
1876 mincount = if timeout, minimum to read before returning
1877 maxcount = number to be read.
1878 time_out = timeout in milliseconds
1879 ****************************************************************************/
1881 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
1887 struct timeval timeout;
1889 /* just checking .... */
1890 if (maxcnt <= 0) return(0);
1895 if (time_out <= 0) {
1896 if (mincnt == 0) mincnt = maxcnt;
1898 while (nread < mincnt) {
1901 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1903 readret = read(fd, buf + nread, maxcnt - nread);
1905 #else /* WITH_SSL */
1906 readret = read(fd, buf + nread, maxcnt - nread);
1907 #endif /* WITH_SSL */
1910 smb_read_error = READ_EOF;
1914 if (readret == -1) {
1915 smb_read_error = READ_ERROR;
1920 return((ssize_t)nread);
1923 /* Most difficult - timeout read */
1924 /* If this is ever called on a disk file and
1925 mincnt is greater then the filesize then
1926 system performance will suffer severely as
1927 select always returns true on disk files */
1929 /* Set initial timeout */
1930 timeout.tv_sec = (time_t)(time_out / 1000);
1931 timeout.tv_usec = (long)(1000 * (time_out % 1000));
1933 for (nread=0; nread < mincnt; )
1938 selrtn = sys_select(fd+1,&fds,&timeout);
1940 /* Check if error */
1942 /* something is wrong. Maybe the socket is dead? */
1943 smb_read_error = READ_ERROR;
1947 /* Did we timeout ? */
1949 smb_read_error = READ_TIMEOUT;
1955 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1957 readret = read(fd, buf + nread, maxcnt - nread);
1959 #else /* WITH_SSL */
1960 readret = read(fd, buf+nread, maxcnt-nread);
1961 #endif /* WITH_SSL */
1964 /* we got EOF on the file descriptor */
1965 smb_read_error = READ_EOF;
1969 if (readret == -1) {
1970 /* the descriptor is probably dead */
1971 smb_read_error = READ_ERROR;
1978 /* Return the number we got */
1979 return((ssize_t)nread);
1982 /*******************************************************************
1983 find the difference in milliseconds between two struct timeval
1985 ********************************************************************/
1986 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
1988 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
1989 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
1992 /****************************************************************************
1993 send a keepalive packet (rfc1002)
1994 ****************************************************************************/
1995 BOOL send_keepalive(int client)
1997 unsigned char buf[4];
2000 buf[1] = buf[2] = buf[3] = 0;
2002 return(write_data(client,(char *)buf,4) == 4);
2007 /****************************************************************************
2008 read data from the client, reading exactly N bytes.
2009 ****************************************************************************/
2010 ssize_t read_data(int fd,char *buffer,size_t N)
2021 ret = SSL_read(ssl, buffer + total, N - total);
2023 ret = read(fd,buffer + total,N - total);
2025 #else /* WITH_SSL */
2026 ret = read(fd,buffer + total,N - total);
2027 #endif /* WITH_SSL */
2031 smb_read_error = READ_EOF;
2036 smb_read_error = READ_ERROR;
2041 return (ssize_t)total;
2045 /****************************************************************************
2047 ****************************************************************************/
2048 ssize_t write_data(int fd,char *buffer,size_t N)
2057 ret = SSL_write(ssl,buffer + total,N - total);
2059 ret = write(fd,buffer + total,N - total);
2061 #else /* WITH_SSL */
2062 ret = write(fd,buffer + total,N - total);
2063 #endif /* WITH_SSL */
2065 if (ret == -1) return -1;
2066 if (ret == 0) return total;
2070 return (ssize_t)total;
2074 /****************************************************************************
2075 transfer some data between two fd's
2076 ****************************************************************************/
2077 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
2079 static char *buf=NULL;
2082 SMB_OFF_T total = 0;
2084 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
2087 size = lp_readsize();
2088 size = MAX(size,1024);
2091 while (!buf && size>0) {
2092 buf = (char *)Realloc(buf,size+8);
2093 if (!buf) size /= 2;
2097 DEBUG(0,("Can't allocate transfer buffer!\n"));
2101 abuf = buf + (align%8);
2108 int s = (int)MIN(n,(SMB_OFF_T)size);
2113 if (header && (headlen >= MIN(s,1024))) {
2123 if (header && headlen > 0)
2125 ret = MIN(headlen,size);
2126 memcpy(buf1,header,ret);
2129 if (headlen <= 0) header = NULL;
2133 ret += read(infd,buf1+ret,s-ret);
2137 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2138 if (ret2 > 0) total += ret2;
2139 /* if we can't write then dump excess data */
2141 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2143 if (ret <= 0 || ret2 != ret)
2151 /****************************************************************************
2152 read 4 bytes of a smb packet and return the smb length of the packet
2153 store the result in the buffer
2154 This version of the function will return a length of zero on receiving
2156 timeout is in milliseconds.
2157 ****************************************************************************/
2158 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
2167 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2169 ok = (read_data(fd,inbuf,4) == 4);
2174 len = smb_len(inbuf);
2175 msg_type = CVAL(inbuf,0);
2177 if (msg_type == 0x85)
2178 DEBUG(5,("Got keepalive packet\n"));
2181 DEBUG(10,("got smb length of %d\n",len));
2186 /****************************************************************************
2187 read 4 bytes of a smb packet and return the smb length of the packet
2188 store the result in the buffer. This version of the function will
2189 never return a session keepalive (length of zero).
2190 timeout is in milliseconds.
2191 ****************************************************************************/
2192 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
2198 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2203 /* Ignore session keepalives. */
2204 if(CVAL(inbuf,0) != 0x85)
2211 /****************************************************************************
2212 read an smb from a fd. Note that the buffer *MUST* be of size
2213 BUFFER_SIZE+SAFETY_MARGIN.
2214 The timeout is in milliseconds.
2215 This function will return on a
2216 receipt of a session keepalive packet.
2217 ****************************************************************************/
2218 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
2224 bzero(buffer,smb_size + 100);
2226 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2230 if (len > BUFFER_SIZE) {
2231 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2232 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2237 ret = read_data(fd,buffer+4,len);
2239 smb_read_error = READ_ERROR;
2246 /****************************************************************************
2247 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2248 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2249 The timeout is in milliseconds
2251 This is exactly the same as receive_smb except that it never returns
2252 a session keepalive packet (just as receive_smb used to do).
2253 receive_smb was changed to return keepalives as the oplock processing means this call
2254 should never go into a blocking read.
2255 ****************************************************************************/
2257 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
2263 ret = receive_smb(fd, buffer, timeout);
2268 /* Ignore session keepalive packets. */
2269 if(CVAL(buffer,0) != 0x85)
2275 /****************************************************************************
2277 ****************************************************************************/
2278 BOOL send_smb(int fd,char *buffer)
2283 len = smb_len(buffer) + 4;
2285 while (nwritten < len)
2287 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2290 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2301 /****************************************************************************
2302 find a pointer to a netbios name
2303 ****************************************************************************/
2304 static char *name_ptr(char *buf,int ofs)
2306 unsigned char c = *(unsigned char *)(buf+ofs);
2308 if ((c & 0xC0) == 0xC0)
2312 memcpy(p,buf+ofs,2);
2315 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2322 /****************************************************************************
2323 extract a netbios name from a buf
2324 ****************************************************************************/
2325 int name_extract(char *buf,int ofs,char *name)
2327 char *p = name_ptr(buf,ofs);
2328 int d = PTR_DIFF(p,buf+ofs);
2330 if (d < -50 || d > 50) return(0);
2331 return(name_interpret(p,name));
2334 /****************************************************************************
2335 return the total storage length of a mangled name
2336 ****************************************************************************/
2337 int name_len(char *s1)
2339 /* NOTE: this argument _must_ be unsigned */
2340 unsigned char *s = (unsigned char *)s1;
2343 /* If the two high bits of the byte are set, return 2. */
2344 if (0xC0 == (*s & 0xC0))
2347 /* Add up the length bytes. */
2348 for (len = 1; (*s); s += (*s) + 1) {
2350 SMB_ASSERT(len < 80);
2356 /****************************************************************************
2357 send a single packet to a port on another machine
2358 ****************************************************************************/
2359 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2363 struct sockaddr_in sock_out;
2368 /* create a socket to write to */
2369 out_fd = socket(AF_INET, type, 0);
2372 DEBUG(0,("socket failed"));
2376 /* set the address and port */
2377 bzero((char *)&sock_out,sizeof(sock_out));
2378 putip((char *)&sock_out.sin_addr,(char *)&ip);
2379 sock_out.sin_port = htons( port );
2380 sock_out.sin_family = AF_INET;
2383 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2384 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2387 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2390 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2391 inet_ntoa(ip),port,strerror(errno)));
2397 /*******************************************************************
2398 sleep for a specified number of milliseconds
2399 ********************************************************************/
2403 struct timeval tval,t1,t2;
2410 tval.tv_sec = (t-tdiff)/1000;
2411 tval.tv_usec = 1000*((t-tdiff)%1000);
2415 sys_select(0,&fds,&tval);
2418 tdiff = TvalDiff(&t1,&t2);
2422 /****************************************************************************
2423 check if a string is part of a list
2424 ****************************************************************************/
2425 BOOL in_list(char *s,char *list,BOOL casesensitive)
2430 if (!list) return(False);
2432 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
2433 if (casesensitive) {
2434 if (strcmp(tok,s) == 0)
2437 if (StrCaseCmp(tok,s) == 0)
2444 /* this is used to prevent lots of mallocs of size 1 */
2445 static char *null_string = NULL;
2447 /****************************************************************************
2448 set a string value, allocing the space for the string
2449 ****************************************************************************/
2450 BOOL string_init(char **dest,char *src)
2461 if((null_string = (char *)malloc(1)) == NULL) {
2462 DEBUG(0,("string_init: malloc fail for null_string.\n"));
2467 *dest = null_string;
2471 (*dest) = (char *)malloc(l+1);
2472 if ((*dest) == NULL) {
2473 DEBUG(0,("Out of memory in string_init\n"));
2482 /****************************************************************************
2484 ****************************************************************************/
2485 void string_free(char **s)
2487 if (!s || !(*s)) return;
2488 if (*s == null_string)
2494 /****************************************************************************
2495 set a string value, allocing the space for the string, and deallocating any
2497 ****************************************************************************/
2498 BOOL string_set(char **dest,char *src)
2502 return(string_init(dest,src));
2505 /****************************************************************************
2506 substitute a string for a pattern in another string. Make sure there is
2509 This routine looks for pattern in s and replaces it with
2510 insert. It may do multiple replacements.
2512 return True if a substitution was done.
2513 ****************************************************************************/
2514 BOOL string_sub(char *s,char *pattern,char *insert)
2520 if (!insert || !pattern || !s) return(False);
2523 lp = strlen(pattern);
2524 li = strlen(insert);
2526 if (!*pattern) return(False);
2528 while (lp <= ls && (p = strstr(s,pattern)))
2531 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2532 memcpy(p,insert,li);
2539 /*********************************************************
2540 * Recursive routine that is called by unix_mask_match.
2541 * Does the actual matching. This is the 'original code'
2542 * used by the unix matcher.
2543 *********************************************************/
2544 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2548 for( p = regexp; *p && *str; ) {
2555 /* Look for a character matching
2556 the one after the '*' */
2559 return True; /* Automatic match */
2561 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2563 if(unix_do_match(str,p,case_sig))
2577 if(toupper(*str) != toupper(*p))
2587 if (!*p && str[0] == '.' && str[1] == 0)
2590 if (!*str && *p == '?')
2592 while (*p == '?') p++;
2596 if(!*str && (*p == '*' && p[1] == '\0'))
2602 /*********************************************************
2603 * Routine to match a given string with a regexp - uses
2604 * simplified regexp that takes * and ? only. Case can be
2605 * significant or not.
2606 * This is the 'original code' used by the unix matcher.
2607 *********************************************************/
2609 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2613 fstring ebase,eext,sbase,sext;
2617 /* Make local copies of str and regexp */
2618 StrnCpy(p1,regexp,sizeof(pstring)-1);
2619 StrnCpy(p2,str,sizeof(pstring)-1);
2621 if (!strchr(p2,'.')) {
2625 /* Remove any *? and ** as they are meaningless */
2626 for(p = p1; *p; p++)
2627 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2628 (void)pstrcpy( &p[1], &p[2]);
2630 if (strequal(p1,"*")) return(True);
2632 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2638 if ((p=strrchr(p1,'.'))) {
2647 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2657 matched = unix_do_match(sbase,ebase,case_sig) &&
2658 (trans2 || unix_do_match(sext,eext,case_sig));
2660 DEBUG(8,("unix_mask_match returning %d\n", matched));
2665 /*********************************************************
2666 * Recursive routine that is called by mask_match.
2667 * Does the actual matching. Returns True if matched,
2668 * False if failed. This is the 'new' NT style matcher.
2669 *********************************************************/
2671 BOOL do_match(char *str, char *regexp, int case_sig)
2675 for( p = regexp; *p && *str; ) {
2682 /* Look for a character matching
2683 the one after the '*' */
2686 return True; /* Automatic match */
2688 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2690 /* Now eat all characters that match, as
2691 we want the *last* character to match. */
2692 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2694 str--; /* We've eaten the match char after the '*' */
2695 if(do_match(str,p,case_sig)) {
2712 if(toupper(*str) != toupper(*p)) {
2724 if (!*p && str[0] == '.' && str[1] == 0) {
2728 if (!*str && *p == '?') {
2734 if(!*str && (*p == '*' && p[1] == '\0')) {
2742 /*********************************************************
2743 * Routine to match a given string with a regexp - uses
2744 * simplified regexp that takes * and ? only. Case can be
2745 * significant or not.
2746 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2747 * This is the new 'NT style' matcher.
2748 *********************************************************/
2750 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2753 pstring t_pattern, t_filename, te_pattern, te_filename;
2754 fstring ebase,eext,sbase,sext;
2756 BOOL matched = False;
2758 /* Make local copies of str and regexp */
2759 pstrcpy(t_pattern,regexp);
2760 pstrcpy(t_filename,str);
2764 * Not sure if this is a good idea. JRA.
2766 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2771 if (!strchr(t_filename,'.')) {
2772 pstrcat(t_filename,".");
2776 /* Remove any *? and ** as they are meaningless */
2777 string_sub(t_pattern, "*?", "*");
2778 string_sub(t_pattern, "**", "*");
2780 if (strequal(t_pattern,"*"))
2783 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2787 * Match each component of the regexp, split up by '.'
2790 char *fp, *rp, *cp2, *cp1;
2791 BOOL last_wcard_was_star = False;
2792 int num_path_components, num_regexp_components;
2794 pstrcpy(te_pattern,t_pattern);
2795 pstrcpy(te_filename,t_filename);
2797 * Remove multiple "*." patterns.
2799 string_sub(te_pattern, "*.*.", "*.");
2800 num_regexp_components = count_chars(te_pattern, '.');
2801 num_path_components = count_chars(te_filename, '.');
2804 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2806 if(num_regexp_components == 0)
2807 matched = do_match( te_filename, te_pattern, case_sig);
2809 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
2810 fp = strchr(cp2, '.');
2813 rp = strchr(cp1, '.');
2817 if(cp1[strlen(cp1)-1] == '*')
2818 last_wcard_was_star = True;
2820 last_wcard_was_star = False;
2822 if(!do_match(cp2, cp1, case_sig))
2825 cp1 = rp ? rp + 1 : NULL;
2826 cp2 = fp ? fp + 1 : "";
2828 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
2829 /* Eat the extra path components. */
2832 for(i = 0; i < num_path_components - num_regexp_components; i++) {
2833 fp = strchr(cp2, '.');
2837 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
2838 cp2 = fp ? fp + 1 : "";
2841 cp2 = fp ? fp + 1 : "";
2843 num_path_components -= i;
2846 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
2851 /* -------------------------------------------------
2852 * Behaviour of Win95
2853 * for 8.3 filenames and 8.3 Wildcards
2854 * -------------------------------------------------
2856 if (strequal (t_filename, ".")) {
2858 * Patterns: *.* *. ?. ? are valid
2861 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2862 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
2864 } else if (strequal (t_filename, "..")) {
2866 * Patterns: *.* *. ?. ? *.? are valid
2869 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2870 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
2871 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
2875 if ((p = strrchr (t_pattern, '.'))) {
2877 * Wildcard has a suffix.
2880 fstrcpy (ebase, t_pattern);
2882 fstrcpy (eext, p + 1);
2884 /* pattern ends in DOT: treat as if there is no DOT */
2886 if (strequal (ebase, "*"))
2891 * No suffix for wildcard.
2893 fstrcpy (ebase, t_pattern);
2897 p = strrchr (t_filename, '.');
2898 if (p && (p[1] == 0) ) {
2900 * Filename has an extension of '.' only.
2902 *p = 0; /* nuke dot at end of string */
2903 p = 0; /* and treat it as if there is no extension */
2908 * Filename has an extension.
2911 fstrcpy (sbase, t_filename);
2912 fstrcpy (sext, p + 1);
2914 matched = do_match(sbase, ebase, case_sig)
2915 && do_match(sext, eext, case_sig);
2917 /* pattern has no extension */
2918 /* Really: match complete filename with pattern ??? means exactly 3 chars */
2919 matched = do_match(str, ebase, case_sig);
2923 * Filename has no extension.
2925 fstrcpy (sbase, t_filename);
2928 /* pattern has extension */
2929 matched = do_match(sbase, ebase, case_sig)
2930 && do_match(sext, eext, case_sig);
2932 matched = do_match(sbase, ebase, case_sig);
2933 #ifdef EMULATE_WEIRD_W95_MATCHING
2935 * Even Microsoft has some problems
2936 * Behaviour Win95 -> local disk
2937 * is different from Win95 -> smb drive from Nt 4.0
2938 * This branch would reflect the Win95 local disk behaviour
2941 /* a? matches aa and a in w95 */
2942 fstrcat (sbase, ".");
2943 matched = do_match(sbase, ebase, case_sig);
2951 DEBUG(8,("mask_match returning %d\n", matched));
2956 /****************************************************************************
2957 become a daemon, discarding the controlling terminal
2958 ****************************************************************************/
2959 void become_daemon(void)
2965 /* detach from the terminal */
2968 #elif defined(TIOCNOTTY)
2970 int i = open("/dev/tty", O_RDWR);
2972 ioctl(i, (int) TIOCNOTTY, (char *)0);
2976 #endif /* HAVE_SETSID */
2978 /* Close fd's 0,1,2. Needed if started by rsh */
2983 /****************************************************************************
2984 put up a yes/no prompt
2985 ****************************************************************************/
2991 if (!fgets(ans,sizeof(ans)-1,stdin))
2994 if (*ans == 'y' || *ans == 'Y')
3000 /****************************************************************************
3001 read a line from a file with possible \ continuation chars.
3002 Blanks at the start or end of a line are stripped.
3003 The string will be allocated if s2 is NULL
3004 ****************************************************************************/
3005 char *fgets_slash(char *s2,int maxlen,FILE *f)
3010 BOOL start_of_line = True;
3017 maxlen = MIN(maxlen,8);
3018 s = (char *)Realloc(s,maxlen);
3021 if (!s || maxlen < 2) return(NULL);
3025 while (len < maxlen-1)
3033 while (len > 0 && s[len-1] == ' ')
3037 if (len > 0 && s[len-1] == '\\')
3040 start_of_line = True;
3045 if (len <= 0 && !s2)
3047 return(len>0?s:NULL);
3052 start_of_line = False;
3056 if (!s2 && len > maxlen-3)
3059 s = (char *)Realloc(s,maxlen);
3060 if (!s) return(NULL);
3068 /****************************************************************************
3069 set the length of a file from a filedescriptor.
3070 Returns 0 on success, -1 on failure.
3071 ****************************************************************************/
3072 int set_filelen(int fd, SMB_OFF_T len)
3074 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3075 extend a file with ftruncate. Provide alternate implementation
3078 #ifdef HAVE_FTRUNCATE_EXTEND
3079 return sys_ftruncate(fd, len);
3083 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
3087 /* Do an fstat to see if the file is longer than
3088 the requested size (call ftruncate),
3089 or shorter, in which case seek to len - 1 and write 1
3091 if(sys_fstat(fd, &st)<0)
3095 if (S_ISFIFO(st.st_mode)) return 0;
3098 if(st.st_size == len)
3100 if(st.st_size > len)
3101 return sys_ftruncate(fd, len);
3103 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
3105 if(write(fd, &c, 1)!=1)
3107 /* Seek to where we were */
3108 if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
3116 /****************************************************************************
3117 this is a version of setbuffer() for those machines that only have setvbuf
3118 ****************************************************************************/
3119 void setbuffer(FILE *f,char *buf,int bufsize)
3121 setvbuf(f,buf,_IOFBF,bufsize);
3126 /****************************************************************************
3127 parse out a filename from a path name. Assumes dos style filenames.
3128 ****************************************************************************/
3129 static char *filename_dos(char *path,char *buf)
3131 char *p = strrchr(path,'\\');
3143 /****************************************************************************
3144 expand a pointer to be a particular size
3145 ****************************************************************************/
3146 void *Realloc(void *p,size_t size)
3152 DEBUG(5,("Realloc asked for 0 bytes\n"));
3157 ret = (void *)malloc(size);
3159 ret = (void *)realloc(p,size);
3162 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3168 /****************************************************************************
3169 get my own name and IP
3170 ****************************************************************************/
3171 BOOL get_myname(char *my_name,struct in_addr *ip)
3178 /* get my host name */
3179 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3181 DEBUG(0,("gethostname failed\n"));
3186 if ((hp = Get_Hostbyname(hostname)) == 0)
3188 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3194 /* split off any parts after an initial . */
3195 char *p = strchr(hostname,'.');
3198 fstrcpy(my_name,hostname);
3202 putip((char *)ip,(char *)hp->h_addr);
3208 /****************************************************************************
3209 true if two IP addresses are equal
3210 ****************************************************************************/
3211 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3214 a1 = ntohl(ip1.s_addr);
3215 a2 = ntohl(ip2.s_addr);
3220 /****************************************************************************
3221 open a socket of the specified type, port and address for incoming data
3222 ****************************************************************************/
3223 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3226 struct sockaddr_in sock;
3230 /* get my host name */
3231 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3232 { DEBUG(0,("gethostname failed\n")); return -1; }
3235 if ((hp = Get_Hostbyname(host_name)) == 0)
3237 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3241 bzero((char *)&sock,sizeof(sock));
3242 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3244 #ifdef HAVE_SOCK_SIN_LEN
3245 sock.sin_len = sizeof(sock);
3247 sock.sin_port = htons( port );
3248 sock.sin_family = hp->h_addrtype;
3249 sock.sin_addr.s_addr = socket_addr;
3250 res = socket(hp->h_addrtype, type, 0);
3252 { DEBUG(0,("socket failed\n")); return -1; }
3256 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3259 /* now we've got a socket - we need to bind it */
3260 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3263 if (port == SMB_PORT || port == NMB_PORT)
3264 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3265 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3268 if (dlevel > 0 && port < 1000)
3271 if (port >= 1000 && port < 9000)
3272 return(open_socket_in(type,port+1,dlevel,socket_addr));
3277 DEBUG(3,("bind succeeded on port %d\n",port));
3283 /****************************************************************************
3284 create an outgoing socket
3285 **************************************************************************/
3286 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3288 struct sockaddr_in sock_out;
3290 int connect_loop = 250; /* 250 milliseconds */
3291 int loops = (timeout * 1000) / connect_loop;
3293 /* create a socket to write to */
3294 res = socket(PF_INET, type, 0);
3296 { DEBUG(0,("socket error\n")); return -1; }
3298 if (type != SOCK_STREAM) return(res);
3300 bzero((char *)&sock_out,sizeof(sock_out));
3301 putip((char *)&sock_out.sin_addr,(char *)addr);
3303 sock_out.sin_port = htons( port );
3304 sock_out.sin_family = PF_INET;
3306 /* set it non-blocking */
3307 set_blocking(res,False);
3309 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3311 /* and connect it to the destination */
3313 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3315 /* Some systems return EAGAIN when they mean EINPROGRESS */
3316 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3317 errno == EAGAIN) && loops--) {
3318 msleep(connect_loop);
3322 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3324 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3330 if (ret < 0 && errno == EISCONN) {
3337 DEBUG(1,("error connecting to %s:%d (%s)\n",
3338 inet_ntoa(*addr),port,strerror(errno)));
3343 /* set it blocking again */
3344 set_blocking(res,True);
3350 /****************************************************************************
3351 interpret a protocol description string, with a default
3352 ****************************************************************************/
3353 int interpret_protocol(char *str,int def)
3355 if (strequal(str,"NT1"))
3356 return(PROTOCOL_NT1);
3357 if (strequal(str,"LANMAN2"))
3358 return(PROTOCOL_LANMAN2);
3359 if (strequal(str,"LANMAN1"))
3360 return(PROTOCOL_LANMAN1);
3361 if (strequal(str,"CORE"))
3362 return(PROTOCOL_CORE);
3363 if (strequal(str,"COREPLUS"))
3364 return(PROTOCOL_COREPLUS);
3365 if (strequal(str,"CORE+"))
3366 return(PROTOCOL_COREPLUS);
3368 DEBUG(0,("Unrecognised protocol level %s\n",str));
3374 /****************************************************************************
3375 interpret an internet address or name into an IP address in 4 byte form
3376 ****************************************************************************/
3377 uint32 interpret_addr(char *str)
3382 BOOL pure_address = True;
3384 if (strcmp(str,"0.0.0.0") == 0) return(0);
3385 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3387 for (i=0; pure_address && str[i]; i++)
3388 if (!(isdigit((int)str[i]) || str[i] == '.'))
3389 pure_address = False;
3391 /* if it's in the form of an IP address then get the lib to interpret it */
3393 res = inet_addr(str);
3395 /* otherwise assume it's a network name of some sort and use
3397 if ((hp = Get_Hostbyname(str)) == 0) {
3398 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3401 if(hp->h_addr == NULL) {
3402 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3405 putip((char *)&res,(char *)hp->h_addr);
3408 if (res == (uint32)-1) return(0);
3413 /*******************************************************************
3414 a convenient addition to interpret_addr()
3415 ******************************************************************/
3416 struct in_addr *interpret_addr2(char *str)
3418 static struct in_addr ret;
3419 uint32 a = interpret_addr(str);
3424 /*******************************************************************
3425 check if an IP is the 0.0.0.0
3426 ******************************************************************/
3427 BOOL zero_ip(struct in_addr ip)
3430 putip((char *)&a,(char *)&ip);
3435 /*******************************************************************
3436 matchname - determine if host name matches IP address
3437 ******************************************************************/
3438 static BOOL matchname(char *remotehost,struct in_addr addr)
3443 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3444 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3449 * Make sure that gethostbyname() returns the "correct" host name.
3450 * Unfortunately, gethostbyname("localhost") sometimes yields
3451 * "localhost.domain". Since the latter host name comes from the
3452 * local DNS, we just have to trust it (all bets are off if the local
3453 * DNS is perverted). We always check the address list, though.
3456 if (strcasecmp(remotehost, hp->h_name)
3457 && strcasecmp(remotehost, "localhost")) {
3458 DEBUG(0,("host name/name mismatch: %s != %s",
3459 remotehost, hp->h_name));
3463 /* Look up the host address in the address list we just got. */
3464 for (i = 0; hp->h_addr_list[i]; i++) {
3465 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3470 * The host name does not map to the original host address. Perhaps
3471 * someone has compromised a name server. More likely someone botched
3472 * it, but that could be dangerous, too.
3475 DEBUG(0,("host name/address mismatch: %s != %s",
3476 inet_ntoa(addr), hp->h_name));
3480 /*******************************************************************
3481 Reset the 'done' variables so after a client process is created
3482 from a fork call these calls will be re-done. This should be
3483 expanded if more variables need reseting.
3484 ******************************************************************/
3486 static BOOL global_client_name_done = False;
3487 static BOOL global_client_addr_done = False;
3489 void reset_globals_after_fork(void)
3491 global_client_name_done = False;
3492 global_client_addr_done = False;
3495 * Re-seed the random crypto generator, so all smbd's
3496 * started from the same parent won't generate the same
3500 unsigned char dummy;
3501 generate_random_buffer( &dummy, 1, True);
3505 /*******************************************************************
3506 return the DNS name of the client
3507 ******************************************************************/
3508 char *client_name(int fd)
3511 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3512 int length = sizeof(sa);
3513 static pstring name_buf;
3515 static int last_fd=-1;
3517 if (global_client_name_done && last_fd == fd)
3521 global_client_name_done = False;
3523 pstrcpy(name_buf,"UNKNOWN");
3529 if (getpeername(fd, &sa, &length) < 0) {
3530 DEBUG(0,("getpeername failed\n"));
3534 /* Look up the remote host name. */
3535 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3536 sizeof(sockin->sin_addr),
3538 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3539 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3541 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3542 if (!matchname(name_buf, sockin->sin_addr)) {
3543 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3544 pstrcpy(name_buf,"UNKNOWN");
3547 global_client_name_done = True;
3551 /*******************************************************************
3552 return the IP addr of the client as a string
3553 ******************************************************************/
3554 char *client_addr(int fd)
3557 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3558 int length = sizeof(sa);
3559 static fstring addr_buf;
3560 static int last_fd = -1;
3562 if (global_client_addr_done && fd == last_fd)
3566 global_client_addr_done = False;
3568 fstrcpy(addr_buf,"0.0.0.0");
3574 if (getpeername(fd, &sa, &length) < 0) {
3575 DEBUG(0,("getpeername failed\n"));
3579 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3581 global_client_addr_done = True;
3585 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3586 /******************************************************************
3587 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3588 Based on a fix from <Thomas.Hepper@icem.de>.
3589 *******************************************************************/
3591 static void strip_mount_options( pstring *str)
3596 while(*p && !isspace(*p))
3598 while(*p && isspace(*p))
3603 pstrcpy(tmp_str, p);
3604 pstrcpy(*str, tmp_str);
3609 /*******************************************************************
3610 Patch from jkf@soton.ac.uk
3611 Split Luke's automount_server into YP lookup and string splitter
3612 so can easily implement automount_path().
3613 As we may end up doing both, cache the last YP result.
3614 *******************************************************************/
3616 #ifdef WITH_NISPLUS_HOME
3617 static char *automount_lookup(char *user_name)
3619 static fstring last_key = "";
3620 static pstring last_value = "";
3622 char *nis_map = (char *)lp_nis_home_map_name();
3624 char nis_domain[NIS_MAXNAMELEN + 1];
3625 char buffer[NIS_MAXATTRVAL + 1];
3630 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3631 nis_domain[NIS_MAXNAMELEN] = '\0';
3633 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3635 if (strcmp(user_name, last_key))
3637 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3638 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3640 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3642 if (result->status != NIS_SUCCESS)
3644 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3645 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3649 object = result->objects.objects_val;
3650 if (object->zo_data.zo_type == ENTRY_OBJ)
3652 entry = &object->zo_data.objdata_u.en_data;
3653 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3654 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3656 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3657 string_sub(last_value, "&", user_name);
3658 fstrcpy(last_key, user_name);
3662 nis_freeresult(result);
3665 strip_mount_options(&last_value);
3667 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3670 #else /* WITH_NISPLUS_HOME */
3671 static char *automount_lookup(char *user_name)
3673 static fstring last_key = "";
3674 static pstring last_value = "";
3676 int nis_error; /* returned by yp all functions */
3677 char *nis_result; /* yp_match inits this */
3678 int nis_result_len; /* and set this */
3679 char *nis_domain; /* yp_get_default_domain inits this */
3680 char *nis_map = (char *)lp_nis_home_map_name();
3682 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3684 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3688 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3690 if (!strcmp(user_name, last_key))
3692 nis_result = last_value;
3693 nis_result_len = strlen(last_value);
3698 if ((nis_error = yp_match(nis_domain, nis_map,
3699 user_name, strlen(user_name),
3700 &nis_result, &nis_result_len)) != 0)
3702 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3703 yperr_string(nis_error), user_name, nis_map));
3705 if (!nis_error && nis_result_len >= sizeof(pstring))
3707 nis_result_len = sizeof(pstring)-1;
3709 fstrcpy(last_key, user_name);
3710 strncpy(last_value, nis_result, nis_result_len);
3711 last_value[nis_result_len] = '\0';
3714 strip_mount_options(&last_value);
3716 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3719 #endif /* WITH_NISPLUS_HOME */
3722 /*******************************************************************
3723 Patch from jkf@soton.ac.uk
3724 This is Luke's original function with the NIS lookup code
3725 moved out to a separate function.
3726 *******************************************************************/
3727 static char *automount_server(char *user_name)
3729 static pstring server_name;
3731 /* use the local machine name as the default */
3732 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3733 pstrcpy(server_name, local_machine);
3735 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3737 if (lp_nis_home_map())
3739 int home_server_len;
3740 char *automount_value = automount_lookup(user_name);
3741 home_server_len = strcspn(automount_value,":");
3742 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3743 if (home_server_len > sizeof(pstring))
3745 home_server_len = sizeof(pstring);
3747 strncpy(server_name, automount_value, home_server_len);
3748 server_name[home_server_len] = '\0';
3752 DEBUG(4,("Home server: %s\n", server_name));
3757 /*******************************************************************
3758 Patch from jkf@soton.ac.uk
3759 Added this to implement %p (NIS auto-map version of %H)
3760 *******************************************************************/
3761 static char *automount_path(char *user_name)
3763 static pstring server_path;
3765 /* use the passwd entry as the default */
3766 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3767 /* pstrcpy() copes with get_home_dir() returning NULL */
3768 pstrcpy(server_path, get_home_dir(user_name));
3770 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3772 if (lp_nis_home_map())
3774 char *home_path_start;
3775 char *automount_value = automount_lookup(user_name);
3776 home_path_start = strchr(automount_value,':');
3777 if (home_path_start != NULL)
3779 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3780 home_path_start?(home_path_start+1):""));
3781 pstrcpy(server_path, home_path_start+1);
3786 DEBUG(4,("Home server path: %s\n", server_path));
3792 /*******************************************************************
3793 sub strings with useful parameters
3794 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3795 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3796 ********************************************************************/
3797 void standard_sub_basic(char *str)
3801 struct passwd *pass;
3802 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3804 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3810 if ((pass = Get_Pwnam(username,False))!=NULL)
3812 string_sub(p,"%G",gidtoname(pass->pw_gid));
3820 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3821 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3822 case 'L' : string_sub(p,"%L", local_machine); break;
3823 case 'M' : string_sub(p,"%M", client_name(Client)); break;
3824 case 'R' : string_sub(p,"%R", remote_proto); break;
3825 case 'T' : string_sub(p,"%T", timestring()); break;
3826 case 'U' : string_sub(p,"%U", username); break;
3827 case 'a' : string_sub(p,"%a", remote_arch); break;
3830 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
3831 string_sub(p,"%d", pidstr);
3834 case 'h' : string_sub(p,"%h", myhostname); break;
3835 case 'm' : string_sub(p,"%m", remote_machine); break;
3836 case 'v' : string_sub(p,"%v", VERSION); break;
3837 case '$' : /* Expand environment variables */
3839 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3850 if ((q = strchr(p,')')) == NULL)
3852 DEBUG(0,("standard_sub_basic: Unterminated environment \
3853 variable [%s]\n", p));
3859 copylen = MIN((q-r),(sizeof(envname)-1));
3860 strncpy(envname,r,copylen);
3861 envname[copylen] = '\0';
3863 if ((envval = getenv(envname)) == NULL)
3865 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3871 copylen = MIN((q+1-p),(sizeof(envname)-1));
3872 strncpy(envname,p,copylen);
3873 envname[copylen] = '\0';
3874 string_sub(p,envname,envval);
3877 case '\0': p++; break; /* don't run off end if last character is % */
3878 default : p+=2; break;
3885 /****************************************************************************
3886 do some standard substitutions in a string
3887 ****************************************************************************/
3888 void standard_sub(connection_struct *conn,char *str)
3892 for (s=str; (p=strchr(s, '%'));s=p) {
3895 if ((home = get_home_dir(conn->user))) {
3896 string_sub(p,"%H",home);
3903 string_sub(p,"%P",conn->connectpath);
3908 lp_servicename(SNUM(conn)));
3913 gidtoname(conn->gid));
3916 string_sub(p,"%u",conn->user);
3919 /* Patch from jkf@soton.ac.uk Left the %N (NIS
3920 * server name) in standard_sub_basic as it is
3921 * a feature for logon servers, hence uses the
3922 * username. The %p (NIS server path) code is
3923 * here as it is used instead of the default
3924 * "path =" string in [homes] and so needs the
3925 * service name, not the username. */
3928 automount_path(lp_servicename(SNUM(conn))));
3932 break; /* don't run off the end of the string
3940 standard_sub_basic(str);
3945 /*******************************************************************
3946 are two IPs on the same subnet?
3947 ********************************************************************/
3948 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3950 uint32 net1,net2,nmask;
3952 nmask = ntohl(mask.s_addr);
3953 net1 = ntohl(ip1.s_addr);
3954 net2 = ntohl(ip2.s_addr);
3956 return((net1 & nmask) == (net2 & nmask));
3960 /*******************************************************************
3961 write a string in unicoode format
3962 ********************************************************************/
3963 int PutUniCode(char *dst,char *src)
3967 dst[ret++] = src[0];
3976 /****************************************************************************
3977 a wrapper for gethostbyname() that tries with all lower and all upper case
3978 if the initial name fails
3979 ****************************************************************************/
3980 struct hostent *Get_Hostbyname(char *name)
3982 char *name2 = strdup(name);
3983 struct hostent *ret;
3987 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3993 * This next test is redundent and causes some systems (with
3994 * broken isalnum() calls) problems.
3999 if (!isalnum(*name2))
4006 ret = sys_gethostbyname(name2);
4013 /* try with all lowercase */
4015 ret = sys_gethostbyname(name2);
4022 /* try with all uppercase */
4024 ret = sys_gethostbyname(name2);
4031 /* nothing works :-( */
4037 /****************************************************************************
4038 check if a process exists. Does this work on all unixes?
4039 ****************************************************************************/
4041 BOOL process_exists(int pid)
4043 return(kill(pid,0) == 0 || errno != ESRCH);
4047 /*******************************************************************
4048 turn a uid into a user name
4049 ********************************************************************/
4050 char *uidtoname(uid_t uid)
4052 static char name[40];
4053 struct passwd *pass = getpwuid(uid);
4054 if (pass) return(pass->pw_name);
4055 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
4060 /*******************************************************************
4061 turn a gid into a group name
4062 ********************************************************************/
4064 char *gidtoname(gid_t gid)
4066 static char name[40];
4067 struct group *grp = getgrgid(gid);
4068 if (grp) return(grp->gr_name);
4069 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
4073 /*******************************************************************
4074 turn a user name into a uid
4075 ********************************************************************/
4076 uid_t nametouid(const char *name)
4078 struct passwd *pass = getpwnam(name);
4079 if (pass) return(pass->pw_uid);
4083 /*******************************************************************
4084 something really nasty happened - panic!
4085 ********************************************************************/
4086 void smb_panic(char *why)
4088 char *cmd = lp_panic_action();
4092 DEBUG(0,("PANIC: %s\n", why));
4097 /*******************************************************************
4098 a readdir wrapper which just returns the file name
4099 ********************************************************************/
4100 char *readdirname(void *p)
4105 if (!p) return(NULL);
4107 ptr = (struct dirent *)readdir(p);
4108 if (!ptr) return(NULL);
4110 dname = ptr->d_name;
4113 if (telldir(p) < 0) return(NULL);
4116 #ifdef HAVE_BROKEN_READDIR
4117 /* using /usr/ucb/cc is BAD */
4123 memcpy(buf, dname, NAMLEN(ptr)+1);
4124 unix_to_dos(buf, True);
4131 /*******************************************************************
4132 Utility function used to decide if the last component
4133 of a path matches a (possibly wildcarded) entry in a namelist.
4134 ********************************************************************/
4136 BOOL is_in_path(char *name, name_compare_entry *namelist)
4138 pstring last_component;
4141 DEBUG(8, ("is_in_path: %s\n", name));
4143 /* if we have no list it's obviously not in the path */
4144 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4146 DEBUG(8,("is_in_path: no name list.\n"));
4150 /* Get the last component of the unix name. */
4151 p = strrchr(name, '/');
4152 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4153 last_component[sizeof(last_component)-1] = '\0';
4155 for(; namelist->name != NULL; namelist++)
4157 if(namelist->is_wild)
4160 * Look for a wildcard match. Use the old
4161 * 'unix style' mask match, rather than the
4164 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4166 DEBUG(8,("is_in_path: mask match succeeded\n"));
4172 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4173 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4175 DEBUG(8,("is_in_path: match succeeded\n"));
4180 DEBUG(8,("is_in_path: match not found\n"));
4185 /*******************************************************************
4186 Strip a '/' separated list into an array of
4187 name_compare_enties structures suitable for
4188 passing to is_in_path(). We do this for
4189 speed so we can pre-parse all the names in the list
4190 and don't do it for each call to is_in_path().
4191 namelist is modified here and is assumed to be
4192 a copy owned by the caller.
4193 We also check if the entry contains a wildcard to
4194 remove a potentially expensive call to mask_match
4196 ********************************************************************/
4198 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4201 char *nameptr = namelist;
4202 int num_entries = 0;
4205 (*ppname_array) = NULL;
4207 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4210 /* We need to make two passes over the string. The
4211 first to count the number of elements, the second
4216 if ( *nameptr == '/' )
4218 /* cope with multiple (useless) /s) */
4222 /* find the next / */
4223 name_end = strchr(nameptr, '/');
4225 /* oops - the last check for a / didn't find one. */
4226 if (name_end == NULL)
4229 /* next segment please */
4230 nameptr = name_end + 1;
4234 if(num_entries == 0)
4237 if(( (*ppname_array) = (name_compare_entry *)malloc(
4238 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4240 DEBUG(0,("set_namearray: malloc fail\n"));
4244 /* Now copy out the names */
4249 if ( *nameptr == '/' )
4251 /* cope with multiple (useless) /s) */
4255 /* find the next / */
4256 if ((name_end = strchr(nameptr, '/')) != NULL)
4261 /* oops - the last check for a / didn't find one. */
4262 if(name_end == NULL)
4265 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4266 (strchr( nameptr, '*')!=NULL));
4267 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4269 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4273 /* next segment please */
4274 nameptr = name_end + 1;
4278 (*ppname_array)[i].name = NULL;
4283 /****************************************************************************
4284 routine to free a namearray.
4285 ****************************************************************************/
4287 void free_namearray(name_compare_entry *name_array)
4292 if(name_array->name != NULL)
4293 free(name_array->name);
4295 free((char *)name_array);
4298 /****************************************************************************
4299 routine to do file locking
4300 ****************************************************************************/
4301 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
4304 SMB_STRUCT_FLOCK lock;
4307 if(lp_ole_locking_compat()) {
4308 SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
4309 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
4311 /* make sure the count is reasonable, we might kill the lockd otherwise */
4314 /* the offset is often strange - remove 2 of its bits if either of
4315 the top two bits are set. Shift the top ones by two bits. This
4316 still allows OLE2 apps to operate, but should stop lockd from
4318 if ((offset & mask) != 0)
4319 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
4321 SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
4322 SMB_OFF_T neg_mask = ~mask;
4324 /* interpret negative counts as large numbers */
4328 /* no negative offsets */
4332 /* count + offset must be in range */
4333 while ((offset < 0 || (offset + count < 0)) && mask)
4336 mask = ((mask >> 1) & neg_mask);
4340 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
4343 lock.l_whence = SEEK_SET;
4344 lock.l_start = offset;
4350 ret = fcntl(fd,op,&lock);
4355 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
4356 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
4357 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
4359 /* 32 bit NFS file system, retry with smaller offset */
4361 lock.l_len = count & 0xffffffff;
4362 ret = fcntl(fd,op,&lock);
4366 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4369 if (op == SMB_F_GETLK)
4372 (lock.l_type != F_UNLCK) &&
4373 (lock.l_pid != 0) &&
4374 (lock.l_pid != getpid()))
4376 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4380 /* it must be not locked or locked by me */
4384 /* a lock set or unset */
4387 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
4388 (double)offset,(double)count,op,type,strerror(errno)));
4390 /* perhaps it doesn't support this sort of locking?? */
4391 if (errno == EINVAL)
4393 DEBUG(3,("locking not supported? returning True\n"));
4400 /* everything went OK */
4401 DEBUG(8,("Lock call successful\n"));
4409 /*******************************************************************
4410 is the name specified one of my netbios names
4411 returns true is it is equal, false otherwise
4412 ********************************************************************/
4413 BOOL is_myname(char *s)
4418 for (n=0; my_netbios_names[n]; n++) {
4419 if (strequal(my_netbios_names[n], s))
4422 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4426 /*******************************************************************
4427 set the horrid remote_arch string based on an enum.
4428 ********************************************************************/
4429 void set_remote_arch(enum remote_arch_types type)
4435 fstrcpy(remote_arch, "WfWg");
4438 fstrcpy(remote_arch, "OS2");
4441 fstrcpy(remote_arch, "Win95");
4444 fstrcpy(remote_arch, "WinNT");
4447 fstrcpy(remote_arch,"Samba");
4450 ra_type = RA_UNKNOWN;
4451 fstrcpy(remote_arch, "UNKNOWN");
4456 /*******************************************************************
4457 Get the remote_arch type.
4458 ********************************************************************/
4459 enum remote_arch_types get_remote_arch(void)
4465 /*******************************************************************
4466 skip past some unicode strings in a buffer
4467 ********************************************************************/
4468 char *skip_unicode_string(char *buf,int n)
4479 /*******************************************************************
4480 Return a ascii version of a unicode string
4481 Hack alert: uses fixed buffer(s) and only handles ascii strings
4482 ********************************************************************/
4484 char *unistrn2(uint16 *buf, int len)
4486 static char lbufs[8][MAXUNI];
4488 char *lbuf = lbufs[nexti];
4491 nexti = (nexti+1)%8;
4493 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4502 /*******************************************************************
4503 Return a ascii version of a unicode string
4504 Hack alert: uses fixed buffer(s) and only handles ascii strings
4505 ********************************************************************/
4507 char *unistr2(uint16 *buf)
4509 static char lbufs[8][MAXUNI];
4511 char *lbuf = lbufs[nexti];
4514 nexti = (nexti+1)%8;
4516 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4525 /*******************************************************************
4526 create a null-terminated unicode string from a null-terminated ascii string.
4527 return number of unicode chars copied, excluding the null character.
4529 only handles ascii strings
4530 ********************************************************************/
4532 int struni2(uint16 *p, char *buf)
4536 if (p == NULL) return 0;
4540 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4551 /*******************************************************************
4552 Return a ascii version of a unicode string
4553 Hack alert: uses fixed buffer(s) and only handles ascii strings
4554 ********************************************************************/
4556 char *unistr(char *buf)
4558 static char lbufs[8][MAXUNI];
4560 char *lbuf = lbufs[nexti];
4563 nexti = (nexti+1)%8;
4565 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4574 /*******************************************************************
4575 strcpy for unicode strings. returns length (in num of wide chars)
4576 ********************************************************************/
4577 int unistrcpy(char *dst, char *src)
4593 /*******************************************************************
4594 safe string copy into a known length string. maxlength does not
4595 include the terminating zero.
4596 ********************************************************************/
4597 char *safe_strcpy(char *dest,const char *src, int maxlength)
4602 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4613 if (len > maxlength) {
4614 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4615 len-maxlength, src));
4619 memcpy(dest, src, len);
4624 /*******************************************************************
4625 safe string cat into a string. maxlength does not
4626 include the terminating zero.
4627 ********************************************************************/
4628 char *safe_strcat(char *dest, char *src, int maxlength)
4630 int src_len, dest_len;
4633 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4641 src_len = strlen(src);
4642 dest_len = strlen(dest);
4644 if (src_len + dest_len > maxlength) {
4645 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4646 src_len + dest_len - maxlength, src));
4647 src_len = maxlength - dest_len;
4650 memcpy(&dest[dest_len], src, src_len);
4651 dest[dest_len + src_len] = 0;
4655 /*******************************************************************
4656 align a pointer to a multiple of 2 bytes
4657 ********************************************************************/
4658 char *align2(char *q, char *base)
4667 void print_asc(int level, unsigned char *buf,int len)
4671 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4674 void dump_data(int level,char *buf1,int len)
4676 unsigned char *buf = (unsigned char *)buf1;
4680 DEBUG(level,("[%03X] ",i));
4682 DEBUG(level,("%02X ",(int)buf[i]));
4684 if (i%8 == 0) DEBUG(level,(" "));
4686 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4687 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4688 if (i<len) DEBUG(level,("[%03X] ",i));
4696 if (n>8) DEBUG(level,(" "));
4697 while (n--) DEBUG(level,(" "));
4700 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4702 if (n>0) print_asc(level,&buf[i-n],n);
4703 DEBUG(level,("\n"));
4707 char *tab_depth(int depth)
4709 static pstring spaces;
4710 memset(spaces, ' ', depth * 4);
4711 spaces[depth * 4] = 0;
4715 /*****************************************************************
4716 Convert a SID to an ascii string.
4717 *****************************************************************/
4719 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
4723 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4724 uint32 ia = (sid->id_auth[5]) +
4725 (sid->id_auth[4] << 8 ) +
4726 (sid->id_auth[3] << 16) +
4727 (sid->id_auth[2] << 24);
4729 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4731 for (i = 0; i < sid->num_auths; i++)
4733 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4734 pstrcat(sidstr_out, subauth);
4737 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
4741 /*****************************************************************
4742 Convert a string to a SID. Returns True on success, False on fail.
4743 *****************************************************************/
4745 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
4749 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4752 memset((char *)sidout, '\0', sizeof(DOM_SID));
4754 if(StrnCaseCmp( sidstr, "S-", 2)) {
4755 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
4760 if(!next_token(&p, tok, "-", sizeof(tok))) {
4761 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4765 /* Get the revision number. */
4766 sidout->sid_rev_num = atoi(tok);
4768 if(!next_token(&p, tok, "-", sizeof(tok))) {
4769 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4773 /* identauth in decimal should be < 2^32 */
4776 /* NOTE - the ia value is in big-endian format. */
4777 sidout->id_auth[0] = 0;
4778 sidout->id_auth[1] = 0;
4779 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
4780 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
4781 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
4782 sidout->id_auth[5] = (ia & 0x000000ff);
4784 sidout->num_auths = 0;
4786 while(next_token(&p, tok, "-", sizeof(tok)) &&
4787 sidout->num_auths < MAXSUBAUTHS) {
4789 * NOTE - the subauths are in native machine-endian format. They
4790 * are converted to little-endian when linearized onto the wire.
4792 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
4795 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
4800 /*****************************************************************************
4801 * Provide a checksum on a string
4803 * Input: s - the nul-terminated character string for which the checksum
4804 * will be calculated.
4806 * Output: The checksum value calculated for s.
4808 * ****************************************************************************
4810 int str_checksum(const char *s)
4818 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
4823 } /* str_checksum */
4827 /*****************************************************************
4828 zero a memory area then free it. Used to catch bugs faster
4829 *****************************************************************/
4830 void zero_free(void *p, size_t size)
4837 /*****************************************************************
4838 set our open file limit to a requested max and return the limit
4839 *****************************************************************/
4840 int set_maxfiles(int requested_max)
4842 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4844 getrlimit(RLIMIT_NOFILE, &rlp);
4845 /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
4846 * account for the extra fd we need
4847 * as well as the log files and standard
4849 rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
4850 setrlimit(RLIMIT_NOFILE, &rlp);
4851 getrlimit(RLIMIT_NOFILE, &rlp);
4852 return rlp.rlim_cur;
4855 * No way to know - just guess...
4857 return requested_max;