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(unsigned char *s)
2341 /* If the two high bits of the byte are set, return 2. */
2342 if (0xC0 == (*s & 0xC0))
2345 /* Add up the length bytes. */
2346 for (len = 1; (*s); s += (*s) + 1) {
2348 SMB_ASSERT(len < 80);
2354 /****************************************************************************
2355 send a single packet to a port on another machine
2356 ****************************************************************************/
2357 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2361 struct sockaddr_in sock_out;
2366 /* create a socket to write to */
2367 out_fd = socket(AF_INET, type, 0);
2370 DEBUG(0,("socket failed"));
2374 /* set the address and port */
2375 bzero((char *)&sock_out,sizeof(sock_out));
2376 putip((char *)&sock_out.sin_addr,(char *)&ip);
2377 sock_out.sin_port = htons( port );
2378 sock_out.sin_family = AF_INET;
2381 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2382 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2385 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2388 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2389 inet_ntoa(ip),port,strerror(errno)));
2395 /*******************************************************************
2396 sleep for a specified number of milliseconds
2397 ********************************************************************/
2401 struct timeval tval,t1,t2;
2408 tval.tv_sec = (t-tdiff)/1000;
2409 tval.tv_usec = 1000*((t-tdiff)%1000);
2413 sys_select(0,&fds,&tval);
2416 tdiff = TvalDiff(&t1,&t2);
2420 /****************************************************************************
2421 check if a string is part of a list
2422 ****************************************************************************/
2423 BOOL in_list(char *s,char *list,BOOL casesensitive)
2428 if (!list) return(False);
2430 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
2431 if (casesensitive) {
2432 if (strcmp(tok,s) == 0)
2435 if (StrCaseCmp(tok,s) == 0)
2442 /* this is used to prevent lots of mallocs of size 1 */
2443 static char *null_string = NULL;
2445 /****************************************************************************
2446 set a string value, allocing the space for the string
2447 ****************************************************************************/
2448 BOOL string_init(char **dest,char *src)
2459 if((null_string = (char *)malloc(1)) == NULL) {
2460 DEBUG(0,("string_init: malloc fail for null_string.\n"));
2465 *dest = null_string;
2469 (*dest) = (char *)malloc(l+1);
2470 if ((*dest) == NULL) {
2471 DEBUG(0,("Out of memory in string_init\n"));
2480 /****************************************************************************
2482 ****************************************************************************/
2483 void string_free(char **s)
2485 if (!s || !(*s)) return;
2486 if (*s == null_string)
2492 /****************************************************************************
2493 set a string value, allocing the space for the string, and deallocating any
2495 ****************************************************************************/
2496 BOOL string_set(char **dest,char *src)
2500 return(string_init(dest,src));
2503 /****************************************************************************
2504 substitute a string for a pattern in another string. Make sure there is
2507 This routine looks for pattern in s and replaces it with
2508 insert. It may do multiple replacements.
2510 return True if a substitution was done.
2511 ****************************************************************************/
2512 BOOL string_sub(char *s,char *pattern,char *insert)
2518 if (!insert || !pattern || !s) return(False);
2521 lp = strlen(pattern);
2522 li = strlen(insert);
2524 if (!*pattern) return(False);
2526 while (lp <= ls && (p = strstr(s,pattern)))
2529 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2530 memcpy(p,insert,li);
2537 /*********************************************************
2538 * Recursive routine that is called by unix_mask_match.
2539 * Does the actual matching. This is the 'original code'
2540 * used by the unix matcher.
2541 *********************************************************/
2542 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2546 for( p = regexp; *p && *str; ) {
2553 /* Look for a character matching
2554 the one after the '*' */
2557 return True; /* Automatic match */
2559 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2561 if(unix_do_match(str,p,case_sig))
2575 if(toupper(*str) != toupper(*p))
2585 if (!*p && str[0] == '.' && str[1] == 0)
2588 if (!*str && *p == '?')
2590 while (*p == '?') p++;
2594 if(!*str && (*p == '*' && p[1] == '\0'))
2600 /*********************************************************
2601 * Routine to match a given string with a regexp - uses
2602 * simplified regexp that takes * and ? only. Case can be
2603 * significant or not.
2604 * This is the 'original code' used by the unix matcher.
2605 *********************************************************/
2607 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2611 fstring ebase,eext,sbase,sext;
2615 /* Make local copies of str and regexp */
2616 StrnCpy(p1,regexp,sizeof(pstring)-1);
2617 StrnCpy(p2,str,sizeof(pstring)-1);
2619 if (!strchr(p2,'.')) {
2623 /* Remove any *? and ** as they are meaningless */
2624 for(p = p1; *p; p++)
2625 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2626 (void)pstrcpy( &p[1], &p[2]);
2628 if (strequal(p1,"*")) return(True);
2630 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2636 if ((p=strrchr(p1,'.'))) {
2645 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2655 matched = unix_do_match(sbase,ebase,case_sig) &&
2656 (trans2 || unix_do_match(sext,eext,case_sig));
2658 DEBUG(8,("unix_mask_match returning %d\n", matched));
2663 /*********************************************************
2664 * Recursive routine that is called by mask_match.
2665 * Does the actual matching. Returns True if matched,
2666 * False if failed. This is the 'new' NT style matcher.
2667 *********************************************************/
2669 BOOL do_match(char *str, char *regexp, int case_sig)
2673 for( p = regexp; *p && *str; ) {
2680 /* Look for a character matching
2681 the one after the '*' */
2684 return True; /* Automatic match */
2686 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2688 /* Now eat all characters that match, as
2689 we want the *last* character to match. */
2690 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2692 str--; /* We've eaten the match char after the '*' */
2693 if(do_match(str,p,case_sig)) {
2710 if(toupper(*str) != toupper(*p)) {
2722 if (!*p && str[0] == '.' && str[1] == 0) {
2726 if (!*str && *p == '?') {
2732 if(!*str && (*p == '*' && p[1] == '\0')) {
2740 /*********************************************************
2741 * Routine to match a given string with a regexp - uses
2742 * simplified regexp that takes * and ? only. Case can be
2743 * significant or not.
2744 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2745 * This is the new 'NT style' matcher.
2746 *********************************************************/
2748 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2751 pstring t_pattern, t_filename, te_pattern, te_filename;
2752 fstring ebase,eext,sbase,sext;
2754 BOOL matched = False;
2756 /* Make local copies of str and regexp */
2757 pstrcpy(t_pattern,regexp);
2758 pstrcpy(t_filename,str);
2762 * Not sure if this is a good idea. JRA.
2764 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2769 if (!strchr(t_filename,'.')) {
2770 pstrcat(t_filename,".");
2774 /* Remove any *? and ** as they are meaningless */
2775 string_sub(t_pattern, "*?", "*");
2776 string_sub(t_pattern, "**", "*");
2778 if (strequal(t_pattern,"*"))
2781 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2785 * Match each component of the regexp, split up by '.'
2788 char *fp, *rp, *cp2, *cp1;
2789 BOOL last_wcard_was_star = False;
2790 int num_path_components, num_regexp_components;
2792 pstrcpy(te_pattern,t_pattern);
2793 pstrcpy(te_filename,t_filename);
2795 * Remove multiple "*." patterns.
2797 string_sub(te_pattern, "*.*.", "*.");
2798 num_regexp_components = count_chars(te_pattern, '.');
2799 num_path_components = count_chars(te_filename, '.');
2802 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2804 if(num_regexp_components == 0)
2805 matched = do_match( te_filename, te_pattern, case_sig);
2807 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
2808 fp = strchr(cp2, '.');
2811 rp = strchr(cp1, '.');
2815 if(cp1[strlen(cp1)-1] == '*')
2816 last_wcard_was_star = True;
2818 last_wcard_was_star = False;
2820 if(!do_match(cp2, cp1, case_sig))
2823 cp1 = rp ? rp + 1 : NULL;
2824 cp2 = fp ? fp + 1 : "";
2826 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
2827 /* Eat the extra path components. */
2830 for(i = 0; i < num_path_components - num_regexp_components; i++) {
2831 fp = strchr(cp2, '.');
2835 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
2836 cp2 = fp ? fp + 1 : "";
2839 cp2 = fp ? fp + 1 : "";
2841 num_path_components -= i;
2844 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
2849 /* -------------------------------------------------
2850 * Behaviour of Win95
2851 * for 8.3 filenames and 8.3 Wildcards
2852 * -------------------------------------------------
2854 if (strequal (t_filename, ".")) {
2856 * Patterns: *.* *. ?. ? are valid
2859 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2860 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
2862 } else if (strequal (t_filename, "..")) {
2864 * Patterns: *.* *. ?. ? *.? are valid
2867 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2868 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
2869 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
2873 if ((p = strrchr (t_pattern, '.'))) {
2875 * Wildcard has a suffix.
2878 fstrcpy (ebase, t_pattern);
2880 fstrcpy (eext, p + 1);
2882 /* pattern ends in DOT: treat as if there is no DOT */
2884 if (strequal (ebase, "*"))
2889 * No suffix for wildcard.
2891 fstrcpy (ebase, t_pattern);
2895 p = strrchr (t_filename, '.');
2896 if (p && (p[1] == 0) ) {
2898 * Filename has an extension of '.' only.
2900 *p = 0; /* nuke dot at end of string */
2901 p = 0; /* and treat it as if there is no extension */
2906 * Filename has an extension.
2909 fstrcpy (sbase, t_filename);
2910 fstrcpy (sext, p + 1);
2912 matched = do_match(sbase, ebase, case_sig)
2913 && do_match(sext, eext, case_sig);
2915 /* pattern has no extension */
2916 /* Really: match complete filename with pattern ??? means exactly 3 chars */
2917 matched = do_match(str, ebase, case_sig);
2921 * Filename has no extension.
2923 fstrcpy (sbase, t_filename);
2926 /* pattern has extension */
2927 matched = do_match(sbase, ebase, case_sig)
2928 && do_match(sext, eext, case_sig);
2930 matched = do_match(sbase, ebase, case_sig);
2931 #ifdef EMULATE_WEIRD_W95_MATCHING
2933 * Even Microsoft has some problems
2934 * Behaviour Win95 -> local disk
2935 * is different from Win95 -> smb drive from Nt 4.0
2936 * This branch would reflect the Win95 local disk behaviour
2939 /* a? matches aa and a in w95 */
2940 fstrcat (sbase, ".");
2941 matched = do_match(sbase, ebase, case_sig);
2949 DEBUG(8,("mask_match returning %d\n", matched));
2954 /****************************************************************************
2955 become a daemon, discarding the controlling terminal
2956 ****************************************************************************/
2957 void become_daemon(void)
2963 /* detach from the terminal */
2966 #elif defined(TIOCNOTTY)
2968 int i = open("/dev/tty", O_RDWR);
2970 ioctl(i, (int) TIOCNOTTY, (char *)0);
2974 #endif /* HAVE_SETSID */
2976 /* Close fd's 0,1,2. Needed if started by rsh */
2981 /****************************************************************************
2982 put up a yes/no prompt
2983 ****************************************************************************/
2989 if (!fgets(ans,sizeof(ans)-1,stdin))
2992 if (*ans == 'y' || *ans == 'Y')
2998 /****************************************************************************
2999 read a line from a file with possible \ continuation chars.
3000 Blanks at the start or end of a line are stripped.
3001 The string will be allocated if s2 is NULL
3002 ****************************************************************************/
3003 char *fgets_slash(char *s2,int maxlen,FILE *f)
3008 BOOL start_of_line = True;
3015 maxlen = MIN(maxlen,8);
3016 s = (char *)Realloc(s,maxlen);
3019 if (!s || maxlen < 2) return(NULL);
3023 while (len < maxlen-1)
3031 while (len > 0 && s[len-1] == ' ')
3035 if (len > 0 && s[len-1] == '\\')
3038 start_of_line = True;
3043 if (len <= 0 && !s2)
3045 return(len>0?s:NULL);
3050 start_of_line = False;
3054 if (!s2 && len > maxlen-3)
3057 s = (char *)Realloc(s,maxlen);
3058 if (!s) return(NULL);
3066 /****************************************************************************
3067 set the length of a file from a filedescriptor.
3068 Returns 0 on success, -1 on failure.
3069 ****************************************************************************/
3070 int set_filelen(int fd, SMB_OFF_T len)
3072 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3073 extend a file with ftruncate. Provide alternate implementation
3076 #ifdef HAVE_FTRUNCATE_EXTEND
3077 return sys_ftruncate(fd, len);
3081 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
3085 /* Do an fstat to see if the file is longer than
3086 the requested size (call ftruncate),
3087 or shorter, in which case seek to len - 1 and write 1
3089 if(sys_fstat(fd, &st)<0)
3093 if (S_ISFIFO(st.st_mode)) return 0;
3096 if(st.st_size == len)
3098 if(st.st_size > len)
3099 return sys_ftruncate(fd, len);
3101 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
3103 if(write(fd, &c, 1)!=1)
3105 /* Seek to where we were */
3106 sys_lseek(fd, currpos, SEEK_SET);
3113 /****************************************************************************
3114 this is a version of setbuffer() for those machines that only have setvbuf
3115 ****************************************************************************/
3116 void setbuffer(FILE *f,char *buf,int bufsize)
3118 setvbuf(f,buf,_IOFBF,bufsize);
3123 /****************************************************************************
3124 parse out a filename from a path name. Assumes dos style filenames.
3125 ****************************************************************************/
3126 static char *filename_dos(char *path,char *buf)
3128 char *p = strrchr(path,'\\');
3140 /****************************************************************************
3141 expand a pointer to be a particular size
3142 ****************************************************************************/
3143 void *Realloc(void *p,size_t size)
3149 DEBUG(5,("Realloc asked for 0 bytes\n"));
3154 ret = (void *)malloc(size);
3156 ret = (void *)realloc(p,size);
3159 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3165 /****************************************************************************
3166 get my own name and IP
3167 ****************************************************************************/
3168 BOOL get_myname(char *my_name,struct in_addr *ip)
3175 /* get my host name */
3176 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3178 DEBUG(0,("gethostname failed\n"));
3183 if ((hp = Get_Hostbyname(hostname)) == 0)
3185 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3191 /* split off any parts after an initial . */
3192 char *p = strchr(hostname,'.');
3195 fstrcpy(my_name,hostname);
3199 putip((char *)ip,(char *)hp->h_addr);
3205 /****************************************************************************
3206 true if two IP addresses are equal
3207 ****************************************************************************/
3208 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3211 a1 = ntohl(ip1.s_addr);
3212 a2 = ntohl(ip2.s_addr);
3217 /****************************************************************************
3218 open a socket of the specified type, port and address for incoming data
3219 ****************************************************************************/
3220 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3223 struct sockaddr_in sock;
3227 /* get my host name */
3228 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3229 { DEBUG(0,("gethostname failed\n")); return -1; }
3232 if ((hp = Get_Hostbyname(host_name)) == 0)
3234 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3238 bzero((char *)&sock,sizeof(sock));
3239 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3241 #ifdef HAVE_SOCK_SIN_LEN
3242 sock.sin_len = sizeof(sock);
3244 sock.sin_port = htons( port );
3245 sock.sin_family = hp->h_addrtype;
3246 sock.sin_addr.s_addr = socket_addr;
3247 res = socket(hp->h_addrtype, type, 0);
3249 { DEBUG(0,("socket failed\n")); return -1; }
3253 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3256 /* now we've got a socket - we need to bind it */
3257 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3260 if (port == SMB_PORT || port == NMB_PORT)
3261 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3262 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3265 if (dlevel > 0 && port < 1000)
3268 if (port >= 1000 && port < 9000)
3269 return(open_socket_in(type,port+1,dlevel,socket_addr));
3274 DEBUG(3,("bind succeeded on port %d\n",port));
3280 /****************************************************************************
3281 create an outgoing socket
3282 **************************************************************************/
3283 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3285 struct sockaddr_in sock_out;
3287 int connect_loop = 250; /* 250 milliseconds */
3288 int loops = (timeout * 1000) / connect_loop;
3290 /* create a socket to write to */
3291 res = socket(PF_INET, type, 0);
3293 { DEBUG(0,("socket error\n")); return -1; }
3295 if (type != SOCK_STREAM) return(res);
3297 bzero((char *)&sock_out,sizeof(sock_out));
3298 putip((char *)&sock_out.sin_addr,(char *)addr);
3300 sock_out.sin_port = htons( port );
3301 sock_out.sin_family = PF_INET;
3303 /* set it non-blocking */
3304 set_blocking(res,False);
3306 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3308 /* and connect it to the destination */
3310 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3312 /* Some systems return EAGAIN when they mean EINPROGRESS */
3313 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3314 errno == EAGAIN) && loops--) {
3315 msleep(connect_loop);
3319 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3321 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3327 if (ret < 0 && errno == EISCONN) {
3334 DEBUG(1,("error connecting to %s:%d (%s)\n",
3335 inet_ntoa(*addr),port,strerror(errno)));
3340 /* set it blocking again */
3341 set_blocking(res,True);
3347 /****************************************************************************
3348 interpret a protocol description string, with a default
3349 ****************************************************************************/
3350 int interpret_protocol(char *str,int def)
3352 if (strequal(str,"NT1"))
3353 return(PROTOCOL_NT1);
3354 if (strequal(str,"LANMAN2"))
3355 return(PROTOCOL_LANMAN2);
3356 if (strequal(str,"LANMAN1"))
3357 return(PROTOCOL_LANMAN1);
3358 if (strequal(str,"CORE"))
3359 return(PROTOCOL_CORE);
3360 if (strequal(str,"COREPLUS"))
3361 return(PROTOCOL_COREPLUS);
3362 if (strequal(str,"CORE+"))
3363 return(PROTOCOL_COREPLUS);
3365 DEBUG(0,("Unrecognised protocol level %s\n",str));
3371 /****************************************************************************
3372 interpret an internet address or name into an IP address in 4 byte form
3373 ****************************************************************************/
3374 uint32 interpret_addr(char *str)
3379 BOOL pure_address = True;
3381 if (strcmp(str,"0.0.0.0") == 0) return(0);
3382 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3384 for (i=0; pure_address && str[i]; i++)
3385 if (!(isdigit((int)str[i]) || str[i] == '.'))
3386 pure_address = False;
3388 /* if it's in the form of an IP address then get the lib to interpret it */
3390 res = inet_addr(str);
3392 /* otherwise assume it's a network name of some sort and use
3394 if ((hp = Get_Hostbyname(str)) == 0) {
3395 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3398 if(hp->h_addr == NULL) {
3399 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3402 putip((char *)&res,(char *)hp->h_addr);
3405 if (res == (uint32)-1) return(0);
3410 /*******************************************************************
3411 a convenient addition to interpret_addr()
3412 ******************************************************************/
3413 struct in_addr *interpret_addr2(char *str)
3415 static struct in_addr ret;
3416 uint32 a = interpret_addr(str);
3421 /*******************************************************************
3422 check if an IP is the 0.0.0.0
3423 ******************************************************************/
3424 BOOL zero_ip(struct in_addr ip)
3427 putip((char *)&a,(char *)&ip);
3432 /*******************************************************************
3433 matchname - determine if host name matches IP address
3434 ******************************************************************/
3435 static BOOL matchname(char *remotehost,struct in_addr addr)
3440 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3441 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3446 * Make sure that gethostbyname() returns the "correct" host name.
3447 * Unfortunately, gethostbyname("localhost") sometimes yields
3448 * "localhost.domain". Since the latter host name comes from the
3449 * local DNS, we just have to trust it (all bets are off if the local
3450 * DNS is perverted). We always check the address list, though.
3453 if (strcasecmp(remotehost, hp->h_name)
3454 && strcasecmp(remotehost, "localhost")) {
3455 DEBUG(0,("host name/name mismatch: %s != %s",
3456 remotehost, hp->h_name));
3460 /* Look up the host address in the address list we just got. */
3461 for (i = 0; hp->h_addr_list[i]; i++) {
3462 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3467 * The host name does not map to the original host address. Perhaps
3468 * someone has compromised a name server. More likely someone botched
3469 * it, but that could be dangerous, too.
3472 DEBUG(0,("host name/address mismatch: %s != %s",
3473 inet_ntoa(addr), hp->h_name));
3477 /*******************************************************************
3478 Reset the 'done' variables so after a client process is created
3479 from a fork call these calls will be re-done. This should be
3480 expanded if more variables need reseting.
3481 ******************************************************************/
3483 static BOOL global_client_name_done = False;
3484 static BOOL global_client_addr_done = False;
3486 void reset_globals_after_fork(void)
3488 global_client_name_done = False;
3489 global_client_addr_done = False;
3492 * Re-seed the random crypto generator, so all smbd's
3493 * started from the same parent won't generate the same
3497 unsigned char dummy;
3498 generate_random_buffer( &dummy, 1, True);
3502 /*******************************************************************
3503 return the DNS name of the client
3504 ******************************************************************/
3505 char *client_name(int fd)
3508 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3509 int length = sizeof(sa);
3510 static pstring name_buf;
3512 static int last_fd=-1;
3514 if (global_client_name_done && last_fd == fd)
3518 global_client_name_done = False;
3520 pstrcpy(name_buf,"UNKNOWN");
3526 if (getpeername(fd, &sa, &length) < 0) {
3527 DEBUG(0,("getpeername failed\n"));
3531 /* Look up the remote host name. */
3532 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3533 sizeof(sockin->sin_addr),
3535 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3536 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3538 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3539 if (!matchname(name_buf, sockin->sin_addr)) {
3540 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3541 pstrcpy(name_buf,"UNKNOWN");
3544 global_client_name_done = True;
3548 /*******************************************************************
3549 return the IP addr of the client as a string
3550 ******************************************************************/
3551 char *client_addr(int fd)
3554 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3555 int length = sizeof(sa);
3556 static fstring addr_buf;
3557 static int last_fd = -1;
3559 if (global_client_addr_done && fd == last_fd)
3563 global_client_addr_done = False;
3565 fstrcpy(addr_buf,"0.0.0.0");
3571 if (getpeername(fd, &sa, &length) < 0) {
3572 DEBUG(0,("getpeername failed\n"));
3576 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3578 global_client_addr_done = True;
3582 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3583 /******************************************************************
3584 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3585 Based on a fix from <Thomas.Hepper@icem.de>.
3586 *******************************************************************/
3588 static void strip_mount_options( pstring *str)
3593 while(*p && !isspace(*p))
3595 while(*p && isspace(*p))
3600 pstrcpy(tmp_str, p);
3601 pstrcpy(*str, tmp_str);
3606 /*******************************************************************
3607 Patch from jkf@soton.ac.uk
3608 Split Luke's automount_server into YP lookup and string splitter
3609 so can easily implement automount_path().
3610 As we may end up doing both, cache the last YP result.
3611 *******************************************************************/
3613 #ifdef WITH_NISPLUS_HOME
3614 static char *automount_lookup(char *user_name)
3616 static fstring last_key = "";
3617 static pstring last_value = "";
3619 char *nis_map = (char *)lp_nis_home_map_name();
3621 char nis_domain[NIS_MAXNAMELEN + 1];
3622 char buffer[NIS_MAXATTRVAL + 1];
3627 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3628 nis_domain[NIS_MAXNAMELEN] = '\0';
3630 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3632 if (strcmp(user_name, last_key))
3634 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3635 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3637 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3639 if (result->status != NIS_SUCCESS)
3641 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3642 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3646 object = result->objects.objects_val;
3647 if (object->zo_data.zo_type == ENTRY_OBJ)
3649 entry = &object->zo_data.objdata_u.en_data;
3650 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3651 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3653 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3654 string_sub(last_value, "&", user_name);
3655 fstrcpy(last_key, user_name);
3659 nis_freeresult(result);
3662 strip_mount_options(&last_value);
3664 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3667 #else /* WITH_NISPLUS_HOME */
3668 static char *automount_lookup(char *user_name)
3670 static fstring last_key = "";
3671 static pstring last_value = "";
3673 int nis_error; /* returned by yp all functions */
3674 char *nis_result; /* yp_match inits this */
3675 int nis_result_len; /* and set this */
3676 char *nis_domain; /* yp_get_default_domain inits this */
3677 char *nis_map = (char *)lp_nis_home_map_name();
3679 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3681 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3685 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3687 if (!strcmp(user_name, last_key))
3689 nis_result = last_value;
3690 nis_result_len = strlen(last_value);
3695 if ((nis_error = yp_match(nis_domain, nis_map,
3696 user_name, strlen(user_name),
3697 &nis_result, &nis_result_len)) != 0)
3699 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3700 yperr_string(nis_error), user_name, nis_map));
3702 if (!nis_error && nis_result_len >= sizeof(pstring))
3704 nis_result_len = sizeof(pstring)-1;
3706 fstrcpy(last_key, user_name);
3707 strncpy(last_value, nis_result, nis_result_len);
3708 last_value[nis_result_len] = '\0';
3711 strip_mount_options(&last_value);
3713 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3716 #endif /* WITH_NISPLUS_HOME */
3719 /*******************************************************************
3720 Patch from jkf@soton.ac.uk
3721 This is Luke's original function with the NIS lookup code
3722 moved out to a separate function.
3723 *******************************************************************/
3724 static char *automount_server(char *user_name)
3726 static pstring server_name;
3728 /* use the local machine name as the default */
3729 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3730 pstrcpy(server_name, local_machine);
3732 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3734 if (lp_nis_home_map())
3736 int home_server_len;
3737 char *automount_value = automount_lookup(user_name);
3738 home_server_len = strcspn(automount_value,":");
3739 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3740 if (home_server_len > sizeof(pstring))
3742 home_server_len = sizeof(pstring);
3744 strncpy(server_name, automount_value, home_server_len);
3745 server_name[home_server_len] = '\0';
3749 DEBUG(4,("Home server: %s\n", server_name));
3754 /*******************************************************************
3755 Patch from jkf@soton.ac.uk
3756 Added this to implement %p (NIS auto-map version of %H)
3757 *******************************************************************/
3758 static char *automount_path(char *user_name)
3760 static pstring server_path;
3762 /* use the passwd entry as the default */
3763 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3764 /* pstrcpy() copes with get_home_dir() returning NULL */
3765 pstrcpy(server_path, get_home_dir(user_name));
3767 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3769 if (lp_nis_home_map())
3771 char *home_path_start;
3772 char *automount_value = automount_lookup(user_name);
3773 home_path_start = strchr(automount_value,':');
3774 if (home_path_start != NULL)
3776 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3777 home_path_start?(home_path_start+1):""));
3778 pstrcpy(server_path, home_path_start+1);
3783 DEBUG(4,("Home server path: %s\n", server_path));
3789 /*******************************************************************
3790 sub strings with useful parameters
3791 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3792 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3793 ********************************************************************/
3794 void standard_sub_basic(char *str)
3798 struct passwd *pass;
3799 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3801 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3807 if ((pass = Get_Pwnam(username,False))!=NULL)
3809 string_sub(p,"%G",gidtoname(pass->pw_gid));
3817 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3818 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3819 case 'L' : string_sub(p,"%L", local_machine); break;
3820 case 'M' : string_sub(p,"%M", client_name(Client)); break;
3821 case 'R' : string_sub(p,"%R", remote_proto); break;
3822 case 'T' : string_sub(p,"%T", timestring()); break;
3823 case 'U' : string_sub(p,"%U", username); break;
3824 case 'a' : string_sub(p,"%a", remote_arch); break;
3827 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
3828 string_sub(p,"%d", pidstr);
3831 case 'h' : string_sub(p,"%h", myhostname); break;
3832 case 'm' : string_sub(p,"%m", remote_machine); break;
3833 case 'v' : string_sub(p,"%v", VERSION); break;
3834 case '$' : /* Expand environment variables */
3836 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3847 if ((q = strchr(p,')')) == NULL)
3849 DEBUG(0,("standard_sub_basic: Unterminated environment \
3850 variable [%s]\n", p));
3856 copylen = MIN((q-r),(sizeof(envname)-1));
3857 strncpy(envname,r,copylen);
3858 envname[copylen] = '\0';
3860 if ((envval = getenv(envname)) == NULL)
3862 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3868 copylen = MIN((q+1-p),(sizeof(envname)-1));
3869 strncpy(envname,p,copylen);
3870 envname[copylen] = '\0';
3871 string_sub(p,envname,envval);
3874 case '\0': p++; break; /* don't run off end if last character is % */
3875 default : p+=2; break;
3882 /****************************************************************************
3883 do some standard substitutions in a string
3884 ****************************************************************************/
3885 void standard_sub(connection_struct *conn,char *str)
3889 for (s=str; (p=strchr(s, '%'));s=p) {
3892 if ((home = get_home_dir(conn->user))) {
3893 string_sub(p,"%H",home);
3900 string_sub(p,"%P",conn->connectpath);
3905 lp_servicename(SNUM(conn)));
3910 gidtoname(conn->gid));
3913 string_sub(p,"%u",conn->user);
3916 /* Patch from jkf@soton.ac.uk Left the %N (NIS
3917 * server name) in standard_sub_basic as it is
3918 * a feature for logon servers, hence uses the
3919 * username. The %p (NIS server path) code is
3920 * here as it is used instead of the default
3921 * "path =" string in [homes] and so needs the
3922 * service name, not the username. */
3925 automount_path(lp_servicename(SNUM(conn))));
3929 break; /* don't run off the end of the string
3937 standard_sub_basic(str);
3942 /*******************************************************************
3943 are two IPs on the same subnet?
3944 ********************************************************************/
3945 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
3947 uint32 net1,net2,nmask;
3949 nmask = ntohl(mask.s_addr);
3950 net1 = ntohl(ip1.s_addr);
3951 net2 = ntohl(ip2.s_addr);
3953 return((net1 & nmask) == (net2 & nmask));
3957 /*******************************************************************
3958 write a string in unicoode format
3959 ********************************************************************/
3960 int PutUniCode(char *dst,char *src)
3964 dst[ret++] = src[0];
3973 /****************************************************************************
3974 a wrapper for gethostbyname() that tries with all lower and all upper case
3975 if the initial name fails
3976 ****************************************************************************/
3977 struct hostent *Get_Hostbyname(char *name)
3979 char *name2 = strdup(name);
3980 struct hostent *ret;
3984 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
3990 * This next test is redundent and causes some systems (with
3991 * broken isalnum() calls) problems.
3996 if (!isalnum(*name2))
4003 ret = sys_gethostbyname(name2);
4010 /* try with all lowercase */
4012 ret = sys_gethostbyname(name2);
4019 /* try with all uppercase */
4021 ret = sys_gethostbyname(name2);
4028 /* nothing works :-( */
4034 /****************************************************************************
4035 check if a process exists. Does this work on all unixes?
4036 ****************************************************************************/
4038 BOOL process_exists(int pid)
4040 return(kill(pid,0) == 0 || errno != ESRCH);
4044 /*******************************************************************
4045 turn a uid into a user name
4046 ********************************************************************/
4047 char *uidtoname(uid_t uid)
4049 static char name[40];
4050 struct passwd *pass = getpwuid(uid);
4051 if (pass) return(pass->pw_name);
4052 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
4057 /*******************************************************************
4058 turn a gid into a group name
4059 ********************************************************************/
4061 char *gidtoname(gid_t gid)
4063 static char name[40];
4064 struct group *grp = getgrgid(gid);
4065 if (grp) return(grp->gr_name);
4066 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
4070 /*******************************************************************
4071 turn a user name into a uid
4072 ********************************************************************/
4073 uid_t nametouid(const char *name)
4075 struct passwd *pass = getpwnam(name);
4076 if (pass) return(pass->pw_uid);
4080 /*******************************************************************
4081 something really nasty happened - panic!
4082 ********************************************************************/
4083 void smb_panic(char *why)
4085 char *cmd = lp_panic_action();
4089 DEBUG(0,("PANIC: %s\n", why));
4094 /*******************************************************************
4095 a readdir wrapper which just returns the file name
4096 ********************************************************************/
4097 char *readdirname(void *p)
4102 if (!p) return(NULL);
4104 ptr = (struct dirent *)readdir(p);
4105 if (!ptr) return(NULL);
4107 dname = ptr->d_name;
4110 if (telldir(p) < 0) return(NULL);
4113 #ifdef HAVE_BROKEN_READDIR
4114 /* using /usr/ucb/cc is BAD */
4120 memcpy(buf, dname, NAMLEN(ptr)+1);
4121 unix_to_dos(buf, True);
4128 /*******************************************************************
4129 Utility function used to decide if the last component
4130 of a path matches a (possibly wildcarded) entry in a namelist.
4131 ********************************************************************/
4133 BOOL is_in_path(char *name, name_compare_entry *namelist)
4135 pstring last_component;
4138 DEBUG(8, ("is_in_path: %s\n", name));
4140 /* if we have no list it's obviously not in the path */
4141 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4143 DEBUG(8,("is_in_path: no name list.\n"));
4147 /* Get the last component of the unix name. */
4148 p = strrchr(name, '/');
4149 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4150 last_component[sizeof(last_component)-1] = '\0';
4152 for(; namelist->name != NULL; namelist++)
4154 if(namelist->is_wild)
4157 * Look for a wildcard match. Use the old
4158 * 'unix style' mask match, rather than the
4161 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4163 DEBUG(8,("is_in_path: mask match succeeded\n"));
4169 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4170 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4172 DEBUG(8,("is_in_path: match succeeded\n"));
4177 DEBUG(8,("is_in_path: match not found\n"));
4182 /*******************************************************************
4183 Strip a '/' separated list into an array of
4184 name_compare_enties structures suitable for
4185 passing to is_in_path(). We do this for
4186 speed so we can pre-parse all the names in the list
4187 and don't do it for each call to is_in_path().
4188 namelist is modified here and is assumed to be
4189 a copy owned by the caller.
4190 We also check if the entry contains a wildcard to
4191 remove a potentially expensive call to mask_match
4193 ********************************************************************/
4195 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4198 char *nameptr = namelist;
4199 int num_entries = 0;
4202 (*ppname_array) = NULL;
4204 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4207 /* We need to make two passes over the string. The
4208 first to count the number of elements, the second
4213 if ( *nameptr == '/' )
4215 /* cope with multiple (useless) /s) */
4219 /* find the next / */
4220 name_end = strchr(nameptr, '/');
4222 /* oops - the last check for a / didn't find one. */
4223 if (name_end == NULL)
4226 /* next segment please */
4227 nameptr = name_end + 1;
4231 if(num_entries == 0)
4234 if(( (*ppname_array) = (name_compare_entry *)malloc(
4235 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4237 DEBUG(0,("set_namearray: malloc fail\n"));
4241 /* Now copy out the names */
4246 if ( *nameptr == '/' )
4248 /* cope with multiple (useless) /s) */
4252 /* find the next / */
4253 if ((name_end = strchr(nameptr, '/')) != NULL)
4258 /* oops - the last check for a / didn't find one. */
4259 if(name_end == NULL)
4262 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4263 (strchr( nameptr, '*')!=NULL));
4264 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4266 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4270 /* next segment please */
4271 nameptr = name_end + 1;
4275 (*ppname_array)[i].name = NULL;
4280 /****************************************************************************
4281 routine to free a namearray.
4282 ****************************************************************************/
4284 void free_namearray(name_compare_entry *name_array)
4289 if(name_array->name != NULL)
4290 free(name_array->name);
4292 free((char *)name_array);
4295 /****************************************************************************
4296 routine to do file locking
4297 ****************************************************************************/
4298 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
4301 SMB_STRUCT_FLOCK lock;
4304 if(lp_ole_locking_compat()) {
4305 SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
4306 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
4308 /* make sure the count is reasonable, we might kill the lockd otherwise */
4311 /* the offset is often strange - remove 2 of its bits if either of
4312 the top two bits are set. Shift the top ones by two bits. This
4313 still allows OLE2 apps to operate, but should stop lockd from
4315 if ((offset & mask) != 0)
4316 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
4318 SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
4319 SMB_OFF_T neg_mask = ~mask;
4321 /* interpret negative counts as large numbers */
4325 /* no negative offsets */
4329 /* count + offset must be in range */
4330 while ((offset < 0 || (offset + count < 0)) && mask)
4333 mask = ((mask >> 1) & neg_mask);
4337 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
4340 lock.l_whence = SEEK_SET;
4341 lock.l_start = offset;
4347 ret = fcntl(fd,op,&lock);
4352 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
4353 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
4354 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
4356 /* 32 bit NFS file system, retry with smaller offset */
4358 lock.l_len = count & 0xffffffff;
4359 ret = fcntl(fd,op,&lock);
4363 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4366 if (op == SMB_F_GETLK)
4369 (lock.l_type != F_UNLCK) &&
4370 (lock.l_pid != 0) &&
4371 (lock.l_pid != getpid()))
4373 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4377 /* it must be not locked or locked by me */
4381 /* a lock set or unset */
4384 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
4385 (double)offset,(double)count,op,type,strerror(errno)));
4387 /* perhaps it doesn't support this sort of locking?? */
4388 if (errno == EINVAL)
4390 DEBUG(3,("locking not supported? returning True\n"));
4397 /* everything went OK */
4398 DEBUG(8,("Lock call successful\n"));
4406 /*******************************************************************
4407 is the name specified one of my netbios names
4408 returns true is it is equal, false otherwise
4409 ********************************************************************/
4410 BOOL is_myname(char *s)
4415 for (n=0; my_netbios_names[n]; n++) {
4416 if (strequal(my_netbios_names[n], s))
4419 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4423 /*******************************************************************
4424 set the horrid remote_arch string based on an enum.
4425 ********************************************************************/
4426 void set_remote_arch(enum remote_arch_types type)
4432 fstrcpy(remote_arch, "WfWg");
4435 fstrcpy(remote_arch, "OS2");
4438 fstrcpy(remote_arch, "Win95");
4441 fstrcpy(remote_arch, "WinNT");
4444 fstrcpy(remote_arch,"Samba");
4447 ra_type = RA_UNKNOWN;
4448 fstrcpy(remote_arch, "UNKNOWN");
4453 /*******************************************************************
4454 Get the remote_arch type.
4455 ********************************************************************/
4456 enum remote_arch_types get_remote_arch(void)
4462 /*******************************************************************
4463 skip past some unicode strings in a buffer
4464 ********************************************************************/
4465 char *skip_unicode_string(char *buf,int n)
4476 /*******************************************************************
4477 Return a ascii version of a unicode string
4478 Hack alert: uses fixed buffer(s) and only handles ascii strings
4479 ********************************************************************/
4481 char *unistrn2(uint16 *buf, int len)
4483 static char lbufs[8][MAXUNI];
4485 char *lbuf = lbufs[nexti];
4488 nexti = (nexti+1)%8;
4490 DEBUG(10, ("unistrn2: "));
4492 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4494 DEBUG(10, ("%4x ", *buf));
4504 /*******************************************************************
4505 Return a ascii version of a unicode string
4506 Hack alert: uses fixed buffer(s) and only handles ascii strings
4507 ********************************************************************/
4509 char *unistr2(uint16 *buf)
4511 static char lbufs[8][MAXUNI];
4513 char *lbuf = lbufs[nexti];
4516 nexti = (nexti+1)%8;
4518 DEBUG(10, ("unistr2: "));
4520 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4522 DEBUG(10, ("%4x ", *buf));
4532 /*******************************************************************
4533 create a null-terminated unicode string from a null-terminated ascii string.
4534 return number of unicode chars copied, excluding the null character.
4536 only handles ascii strings
4537 ********************************************************************/
4539 int struni2(uint16 *p, char *buf)
4543 if (p == NULL) return 0;
4545 DEBUG(10, ("struni2: "));
4549 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4551 DEBUG(10, ("%2x ", *buf));
4563 /*******************************************************************
4564 Return a ascii version of a unicode string
4565 Hack alert: uses fixed buffer(s) and only handles ascii strings
4566 ********************************************************************/
4568 char *unistr(char *buf)
4570 static char lbufs[8][MAXUNI];
4572 char *lbuf = lbufs[nexti];
4575 nexti = (nexti+1)%8;
4577 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4586 /*******************************************************************
4587 strcpy for unicode strings. returns length (in num of wide chars)
4588 ********************************************************************/
4589 int unistrcpy(char *dst, char *src)
4605 /*******************************************************************
4606 safe string copy into a known length string. maxlength does not
4607 include the terminating zero.
4608 ********************************************************************/
4609 char *safe_strcpy(char *dest,const char *src, int maxlength)
4614 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4625 if (len > maxlength) {
4626 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4627 len-maxlength, src));
4631 memcpy(dest, src, len);
4636 /*******************************************************************
4637 safe string cat into a string. maxlength does not
4638 include the terminating zero.
4639 ********************************************************************/
4640 char *safe_strcat(char *dest, char *src, int maxlength)
4642 int src_len, dest_len;
4645 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4653 src_len = strlen(src);
4654 dest_len = strlen(dest);
4656 if (src_len + dest_len > maxlength) {
4657 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4658 src_len + dest_len - maxlength, src));
4659 src_len = maxlength - dest_len;
4662 memcpy(&dest[dest_len], src, src_len);
4663 dest[dest_len + src_len] = 0;
4667 /*******************************************************************
4668 align a pointer to a multiple of 2 bytes
4669 ********************************************************************/
4670 char *align2(char *q, char *base)
4679 void print_asc(int level, unsigned char *buf,int len)
4683 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4686 void dump_data(int level,char *buf1,int len)
4688 unsigned char *buf = (unsigned char *)buf1;
4692 DEBUG(level,("[%03X] ",i));
4694 DEBUG(level,("%02X ",(int)buf[i]));
4696 if (i%8 == 0) DEBUG(level,(" "));
4698 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4699 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4700 if (i<len) DEBUG(level,("[%03X] ",i));
4708 if (n>8) DEBUG(level,(" "));
4709 while (n--) DEBUG(level,(" "));
4712 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4714 if (n>0) print_asc(level,&buf[i-n],n);
4715 DEBUG(level,("\n"));
4719 char *tab_depth(int depth)
4721 static pstring spaces;
4722 memset(spaces, ' ', depth * 4);
4723 spaces[depth * 4] = 0;
4727 /*****************************************************************
4728 Convert a SID to an ascii string.
4729 *****************************************************************/
4731 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
4735 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4736 uint32 ia = (sid->id_auth[5]) +
4737 (sid->id_auth[4] << 8 ) +
4738 (sid->id_auth[3] << 16) +
4739 (sid->id_auth[2] << 24);
4741 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4743 for (i = 0; i < sid->num_auths; i++)
4745 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4746 pstrcat(sidstr_out, subauth);
4749 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
4753 /*****************************************************************
4754 Convert a string to a SID. Returns True on success, False on fail.
4755 *****************************************************************/
4757 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
4761 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4764 memset((char *)sidout, '\0', sizeof(DOM_SID));
4766 if(StrnCaseCmp( sidstr, "S-", 2)) {
4767 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
4772 if(!next_token(&p, tok, "-", sizeof(tok))) {
4773 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4777 /* Get the revision number. */
4778 sidout->sid_rev_num = atoi(tok);
4780 if(!next_token(&p, tok, "-", sizeof(tok))) {
4781 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4785 /* identauth in decimal should be < 2^32 */
4788 /* NOTE - the ia value is in big-endian format. */
4789 sidout->id_auth[0] = 0;
4790 sidout->id_auth[1] = 0;
4791 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
4792 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
4793 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
4794 sidout->id_auth[5] = (ia & 0x000000ff);
4796 sidout->num_auths = 0;
4798 while(next_token(&p, tok, "-", sizeof(tok)) &&
4799 sidout->num_auths < MAXSUBAUTHS) {
4801 * NOTE - the subauths are in native machine-endian format. They
4802 * are converted to little-endian when linearized onto the wire.
4804 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
4807 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
4812 /*****************************************************************************
4813 * Provide a checksum on a string
4815 * Input: s - the nul-terminated character string for which the checksum
4816 * will be calculated.
4818 * Output: The checksum value calculated for s.
4820 * ****************************************************************************
4822 int str_checksum(const char *s)
4830 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
4835 } /* str_checksum */
4839 /*****************************************************************
4840 zero a memory area then free it. Used to catch bugs faster
4841 *****************************************************************/
4842 void zero_free(void *p, size_t size)