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 void set_first_token(char *ptr)
133 /****************************************************************************
134 Get the next token from a string, return False if none found
135 handles double-quotes.
136 Based on a routine by GJC@VILLAGE.COM.
137 Extensively modified by Andrew.Tridgell@anu.edu.au
138 ****************************************************************************/
139 BOOL next_token(char **ptr,char *buff,char *sep, int bufsize)
145 if (!ptr) ptr = &last_ptr;
146 if (!ptr) return(False);
150 /* default to simple separators */
151 if (!sep) sep = " \t\n\r";
153 /* find the first non sep char */
154 while(*s && strchr(sep,*s)) s++;
157 if (! *s) return(False);
159 /* copy over the token */
160 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
170 *ptr = (*s) ? s+1 : s;
177 /****************************************************************************
178 Convert list of tokens to array; dependent on above routine.
179 Uses last_ptr from above - bit of a hack.
180 ****************************************************************************/
181 char **toktocliplist(int *ctok, char *sep)
187 if (!sep) sep = " \t\n\r";
189 while(*s && strchr(sep,*s)) s++;
192 if (!*s) return(NULL);
196 while(*s && (!strchr(sep,*s))) s++;
197 while(*s && strchr(sep,*s)) *s++=0;
203 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
214 /****************************************************************************
215 prompte a dptr (to make it recently used)
216 ****************************************************************************/
217 static void array_promote(char *array,int elsize,int element)
223 p = (char *)malloc(elsize);
227 DEBUG(5,("Ahh! Can't malloc\n"));
230 memcpy(p,array + element * elsize, elsize);
231 memmove(array + elsize,array,elsize*element);
232 memcpy(array,p,elsize);
236 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
245 } socket_options[] = {
246 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
247 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
248 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
250 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
252 #ifdef IPTOS_LOWDELAY
253 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
255 #ifdef IPTOS_THROUGHPUT
256 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
259 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
262 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
265 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
268 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
271 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
274 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
280 /****************************************************************************
281 set user socket options
282 ****************************************************************************/
283 void set_socket_options(int fd, char *options)
287 while (next_token(&options,tok," \t,", sizeof(tok)))
292 BOOL got_value = False;
294 if ((p = strchr(tok,'=')))
301 for (i=0;socket_options[i].name;i++)
302 if (strequal(socket_options[i].name,tok))
305 if (!socket_options[i].name)
307 DEBUG(0,("Unknown socket option %s\n",tok));
311 switch (socket_options[i].opttype)
315 ret = setsockopt(fd,socket_options[i].level,
316 socket_options[i].option,(char *)&value,sizeof(int));
321 DEBUG(0,("syntax error - %s does not take a value\n",tok));
324 int on = socket_options[i].value;
325 ret = setsockopt(fd,socket_options[i].level,
326 socket_options[i].option,(char *)&on,sizeof(int));
332 DEBUG(0,("Failed to set socket option %s\n",tok));
338 /****************************************************************************
339 close the socket communication
340 ****************************************************************************/
341 void close_sockets(void )
344 sslutil_disconnect(Client);
345 #endif /* WITH_SSL */
351 /****************************************************************************
352 determine whether we are in the specified group
353 ****************************************************************************/
355 BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
359 if (group == current_gid) return(True);
361 for (i=0;i<ngroups;i++)
362 if (group == groups[i])
368 /****************************************************************************
369 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
370 ****************************************************************************/
371 char *StrCpy(char *dest,char *src)
375 /* I don't want to get lazy with these ... */
376 SMB_ASSERT(dest && src);
378 if (!dest) return(NULL);
383 while ((*d++ = *src++)) ;
387 /****************************************************************************
388 line strncpy but always null terminates. Make sure there is room!
389 ****************************************************************************/
390 char *StrnCpy(char *dest,char *src,int n)
393 if (!dest) return(NULL);
398 while (n-- && (*d++ = *src++)) ;
404 /*******************************************************************
405 copy an IP address from one buffer to another
406 ********************************************************************/
407 void putip(void *dest,void *src)
413 #define TRUNCATE_NETBIOS_NAME 1
415 /*******************************************************************
416 convert, possibly using a stupid microsoft-ism which has destroyed
417 the transport independence of netbios (for CIFS vendors that usually
418 use the Win95-type methods, not for NT to NT communication, which uses
419 DCE/RPC and therefore full-length unicode strings...) a dns name into
422 the netbios name (NOT necessarily null-terminated) is truncated to 15
425 ******************************************************************/
426 char *dns_to_netbios_name(char *dns_name)
428 static char netbios_name[16];
430 StrnCpy(netbios_name, dns_name, 15);
431 netbios_name[15] = 0;
433 #ifdef TRUNCATE_NETBIOS_NAME
434 /* ok. this is because of a stupid microsoft-ism. if the called host
435 name contains a '.', microsoft clients expect you to truncate the
436 netbios name up to and including the '.' this even applies, by
437 mistake, to workgroup (domain) names, which is _really_ daft.
439 for (i = 15; i >= 0; i--)
441 if (netbios_name[i] == '.')
447 #endif /* TRUNCATE_NETBIOS_NAME */
453 /****************************************************************************
454 interpret the weird netbios "name". Return the name type
455 ****************************************************************************/
456 static int name_interpret(char *in,char *out)
459 int len = (*in++) / 2;
463 if (len > 30 || len<1) return(0);
467 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
471 *out = ((in[0]-'A')<<4) + (in[1]-'A');
479 /* Handle any scope names */
482 *out++ = '.'; /* Scope names are separated by periods */
483 len = *(unsigned char *)in++;
484 StrnCpy(out, in, len);
493 /****************************************************************************
494 mangle a name into netbios format
496 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
497 ****************************************************************************/
498 int name_mangle( char *In, char *Out, char name_type )
506 /* Safely copy the input string, In, into buf[]. */
507 (void)memset( buf, 0, 20 );
508 if (strcmp(In,"*") == 0)
511 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
513 /* Place the length of the first field into the output buffer. */
517 /* Now convert the name to the rfc1001/1002 format. */
518 for( i = 0; i < 16; i++ )
520 c = toupper( buf[i] );
521 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
522 p[(i*2)+1] = (c & 0x000F) + 'A';
527 /* Add the scope string. */
528 for( i = 0, len = 0; NULL != scope; i++, len++ )
536 return( name_len(Out) );
548 return( name_len(Out) );
551 /*******************************************************************
552 check if a file exists
553 ********************************************************************/
554 BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
557 if (!sbuf) sbuf = &st;
559 if (dos_stat(fname,sbuf) != 0)
562 return(S_ISREG(sbuf->st_mode));
565 /*******************************************************************
566 check a files mod time
567 ********************************************************************/
568 time_t file_modtime(char *fname)
572 if (dos_stat(fname,&st) != 0)
578 /*******************************************************************
579 check if a directory exists
580 ********************************************************************/
581 BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
588 if (dos_stat(dname,st) != 0)
591 ret = S_ISDIR(st->st_mode);
597 /*******************************************************************
598 returns the size in bytes of the named file
599 ********************************************************************/
600 SMB_OFF_T file_size(char *file_name)
604 dos_stat(file_name,&buf);
608 /*******************************************************************
609 return a string representing an attribute for a file
610 ********************************************************************/
611 char *attrib_string(int mode)
613 static fstring attrstr;
617 if (mode & aVOLID) fstrcat(attrstr,"V");
618 if (mode & aDIR) fstrcat(attrstr,"D");
619 if (mode & aARCH) fstrcat(attrstr,"A");
620 if (mode & aHIDDEN) fstrcat(attrstr,"H");
621 if (mode & aSYSTEM) fstrcat(attrstr,"S");
622 if (mode & aRONLY) fstrcat(attrstr,"R");
628 /*******************************************************************
629 case insensitive string compararison
630 ********************************************************************/
631 int StrCaseCmp(char *s, char *t)
633 /* compare until we run out of string, either t or s, or find a difference */
634 /* We *must* use toupper rather than tolower here due to the
635 asynchronous upper to lower mapping.
637 #if !defined(KANJI_WIN95_COMPATIBILITY)
639 * For completeness we should put in equivalent code for code pages
640 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
641 * doubt anyone wants Samba to behave differently from Win95 and WinNT
642 * here. They both treat full width ascii characters as case senstive
643 * filenames (ie. they don't do the work we do here).
647 if(lp_client_code_page() == KANJI_CODEPAGE)
649 /* Win95 treats full width ascii characters as case sensitive. */
654 return toupper (*s) - toupper (*t);
655 else if (is_sj_alph (*s) && is_sj_alph (*t))
657 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
663 else if (is_shift_jis (*s) && is_shift_jis (*t))
665 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
668 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
674 else if (is_shift_jis (*s))
676 else if (is_shift_jis (*t))
680 diff = toupper (*s) - toupper (*t);
689 #endif /* KANJI_WIN95_COMPATIBILITY */
691 while (*s && *t && toupper(*s) == toupper(*t))
697 return(toupper(*s) - toupper(*t));
701 /*******************************************************************
702 case insensitive string compararison, length limited
703 ********************************************************************/
704 int StrnCaseCmp(char *s, char *t, int n)
706 /* compare until we run out of string, either t or s, or chars */
707 /* We *must* use toupper rather than tolower here due to the
708 asynchronous upper to lower mapping.
710 #if !defined(KANJI_WIN95_COMPATIBILITY)
712 * For completeness we should put in equivalent code for code pages
713 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
714 * doubt anyone wants Samba to behave differently from Win95 and WinNT
715 * here. They both treat full width ascii characters as case senstive
716 * filenames (ie. they don't do the work we do here).
720 if(lp_client_code_page() == KANJI_CODEPAGE)
722 /* Win95 treats full width ascii characters as case sensitive. */
727 return toupper (*s) - toupper (*t);
728 else if (is_sj_alph (*s) && is_sj_alph (*t))
730 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
737 else if (is_shift_jis (*s) && is_shift_jis (*t))
739 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
742 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
749 else if (is_shift_jis (*s))
751 else if (is_shift_jis (*t))
755 diff = toupper (*s) - toupper (*t);
766 #endif /* KANJI_WIN95_COMPATIBILITY */
768 while (n && *s && *t && toupper(*s) == toupper(*t))
775 /* not run out of chars - strings are different lengths */
777 return(toupper(*s) - toupper(*t));
779 /* identical up to where we run out of chars,
780 and strings are same length */
785 /*******************************************************************
787 ********************************************************************/
788 BOOL strequal(char *s1, char *s2)
790 if (s1 == s2) return(True);
791 if (!s1 || !s2) return(False);
793 return(StrCaseCmp(s1,s2)==0);
796 /*******************************************************************
797 compare 2 strings up to and including the nth char.
798 ******************************************************************/
799 BOOL strnequal(char *s1,char *s2,int n)
801 if (s1 == s2) return(True);
802 if (!s1 || !s2 || !n) return(False);
804 return(StrnCaseCmp(s1,s2,n)==0);
807 /*******************************************************************
808 compare 2 strings (case sensitive)
809 ********************************************************************/
810 BOOL strcsequal(char *s1,char *s2)
812 if (s1 == s2) return(True);
813 if (!s1 || !s2) return(False);
815 return(strcmp(s1,s2)==0);
819 /*******************************************************************
820 convert a string to lower case
821 ********************************************************************/
822 void strlower(char *s)
826 #if !defined(KANJI_WIN95_COMPATIBILITY)
828 * For completeness we should put in equivalent code for code pages
829 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
830 * doubt anyone wants Samba to behave differently from Win95 and WinNT
831 * here. They both treat full width ascii characters as case senstive
832 * filenames (ie. they don't do the work we do here).
836 if(lp_client_code_page() == KANJI_CODEPAGE)
838 /* Win95 treats full width ascii characters as case sensitive. */
839 if (is_shift_jis (*s))
841 if (is_sj_upper (s[0], s[1]))
842 s[1] = sj_tolower2 (s[1]);
845 else if (is_kana (*s))
857 #endif /* KANJI_WIN95_COMPATIBILITY */
859 int skip = skip_multibyte_char( *s );
872 /*******************************************************************
873 convert a string to upper case
874 ********************************************************************/
875 void strupper(char *s)
879 #if !defined(KANJI_WIN95_COMPATIBILITY)
881 * For completeness we should put in equivalent code for code pages
882 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
883 * doubt anyone wants Samba to behave differently from Win95 and WinNT
884 * here. They both treat full width ascii characters as case senstive
885 * filenames (ie. they don't do the work we do here).
889 if(lp_client_code_page() == KANJI_CODEPAGE)
891 /* Win95 treats full width ascii characters as case sensitive. */
892 if (is_shift_jis (*s))
894 if (is_sj_lower (s[0], s[1]))
895 s[1] = sj_toupper2 (s[1]);
898 else if (is_kana (*s))
910 #endif /* KANJI_WIN95_COMPATIBILITY */
912 int skip = skip_multibyte_char( *s );
925 /*******************************************************************
926 convert a string to "normal" form
927 ********************************************************************/
928 void strnorm(char *s)
930 if (case_default == CASE_UPPER)
936 /*******************************************************************
937 check if a string is in "normal" case
938 ********************************************************************/
939 BOOL strisnormal(char *s)
941 if (case_default == CASE_UPPER)
942 return(!strhaslower(s));
944 return(!strhasupper(s));
948 /****************************************************************************
950 ****************************************************************************/
951 void string_replace(char *s,char oldc,char newc)
956 skip = skip_multibyte_char( *s );
968 /****************************************************************************
969 make a file into unix format
970 ****************************************************************************/
971 void unix_format(char *fname)
973 string_replace(fname,'\\','/');
976 /****************************************************************************
977 make a file into dos format
978 ****************************************************************************/
979 void dos_format(char *fname)
981 string_replace(fname,'/','\\');
984 /*******************************************************************
985 show a smb message structure
986 ********************************************************************/
987 void show_msg(char *buf)
992 if (DEBUGLEVEL < 5) return;
994 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
996 (int)CVAL(buf,smb_com),
997 (int)CVAL(buf,smb_rcls),
998 (int)CVAL(buf,smb_reh),
999 (int)SVAL(buf,smb_err),
1000 (int)CVAL(buf,smb_flg),
1001 (int)SVAL(buf,smb_flg2)));
1002 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1003 (int)SVAL(buf,smb_tid),
1004 (int)SVAL(buf,smb_pid),
1005 (int)SVAL(buf,smb_uid),
1006 (int)SVAL(buf,smb_mid),
1007 (int)CVAL(buf,smb_wct)));
1009 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1011 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1012 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1015 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1017 DEBUG(5,("smb_bcc=%d\n",bcc));
1019 if (DEBUGLEVEL < 10) return;
1021 if (DEBUGLEVEL < 50)
1023 bcc = MIN(bcc, 512);
1026 dump_data(10, smb_buf(buf), bcc);
1028 /*******************************************************************
1029 return the length of an smb packet
1030 ********************************************************************/
1031 int smb_len(char *buf)
1033 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1036 /*******************************************************************
1037 set the length of an smb packet
1038 ********************************************************************/
1039 void _smb_setlen(char *buf,int len)
1042 buf[1] = (len&0x10000)>>16;
1043 buf[2] = (len&0xFF00)>>8;
1047 /*******************************************************************
1048 set the length and marker of an smb packet
1049 ********************************************************************/
1050 void smb_setlen(char *buf,int len)
1052 _smb_setlen(buf,len);
1060 /*******************************************************************
1061 setup the word count and byte count for a smb message
1062 ********************************************************************/
1063 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1066 bzero(buf + smb_size,num_words*2 + num_bytes);
1067 CVAL(buf,smb_wct) = num_words;
1068 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1069 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1070 return (smb_size + num_words*2 + num_bytes);
1073 /*******************************************************************
1074 return the number of smb words
1075 ********************************************************************/
1076 static int smb_numwords(char *buf)
1078 return (CVAL(buf,smb_wct));
1081 /*******************************************************************
1082 return the size of the smb_buf region of a message
1083 ********************************************************************/
1084 int smb_buflen(char *buf)
1086 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1089 /*******************************************************************
1090 return a pointer to the smb_buf data area
1091 ********************************************************************/
1092 static int smb_buf_ofs(char *buf)
1094 return (smb_size + CVAL(buf,smb_wct)*2);
1097 /*******************************************************************
1098 return a pointer to the smb_buf data area
1099 ********************************************************************/
1100 char *smb_buf(char *buf)
1102 return (buf + smb_buf_ofs(buf));
1105 /*******************************************************************
1106 return the SMB offset into an SMB buffer
1107 ********************************************************************/
1108 int smb_offset(char *p,char *buf)
1110 return(PTR_DIFF(p,buf+4) + chain_size);
1114 /*******************************************************************
1115 skip past some strings in a buffer
1116 ********************************************************************/
1117 char *skip_string(char *buf,int n)
1120 buf += strlen(buf) + 1;
1124 /*******************************************************************
1125 Count the number of characters in a string. Normally this will
1126 be the same as the number of bytes in a string for single byte strings,
1127 but will be different for multibyte.
1128 16.oct.98, jdblair@cobaltnet.com.
1129 ********************************************************************/
1131 size_t str_charnum(char *s)
1135 while (*s != '\0') {
1136 int skip = skip_multibyte_char(*s);
1137 s += (skip ? skip : 1);
1143 /*******************************************************************
1144 trim the specified elements off the front and back of a string
1145 ********************************************************************/
1147 BOOL trim_string(char *s,char *front,char *back)
1150 size_t front_len = (front && *front) ? strlen(front) : 0;
1151 size_t back_len = (back && *back) ? strlen(back) : 0;
1154 while (front_len && strncmp(s, front, front_len) == 0)
1160 if (!(*p = p[front_len]))
1167 * We split out the multibyte code page
1168 * case here for speed purposes. Under a
1169 * multibyte code page we need to walk the
1170 * string forwards only and multiple times.
1171 * Thanks to John Blair for finding this
1177 if(!is_multibyte_codepage())
1180 while ((s_len >= back_len) &&
1181 (strncmp(s + s_len - back_len, back, back_len)==0))
1184 s[s_len - back_len] = '\0';
1192 * Multibyte code page case.
1193 * Keep going through the string, trying
1194 * to match the 'back' string with the end
1195 * of the string. If we get a match, truncate
1196 * 'back' off the end of the string and
1197 * go through the string again from the
1198 * start. Keep doing this until we have
1199 * gone through the string with no match
1200 * at the string end.
1203 size_t mb_back_len = str_charnum(back);
1204 size_t mb_s_len = str_charnum(s);
1206 while(mb_s_len >= mb_back_len)
1208 size_t charcount = 0;
1211 while(charcount < (mb_s_len - mb_back_len))
1213 size_t skip = skip_multibyte_char(*mbp);
1214 mbp += (skip ? skip : 1);
1219 * mbp now points at mb_back_len multibyte
1220 * characters from the end of s.
1223 if(strcmp(mbp, back) == 0)
1227 mb_s_len = str_charnum(s);
1232 } /* end while mb_s_len... */
1234 } /* end if back_len .. */
1240 /*******************************************************************
1241 reduce a file name, removing .. elements.
1242 ********************************************************************/
1243 void dos_clean_name(char *s)
1247 DEBUG(3,("dos_clean_name [%s]\n",s));
1249 /* remove any double slashes */
1250 string_sub(s, "\\\\", "\\");
1252 while ((p = strstr(s,"\\..\\")) != NULL)
1259 if ((p=strrchr(s,'\\')) != NULL)
1266 trim_string(s,NULL,"\\..");
1268 string_sub(s, "\\.\\", "\\");
1271 /*******************************************************************
1272 reduce a file name, removing .. elements.
1273 ********************************************************************/
1274 void unix_clean_name(char *s)
1278 DEBUG(3,("unix_clean_name [%s]\n",s));
1280 /* remove any double slashes */
1281 string_sub(s, "//","/");
1283 /* Remove leading ./ characters */
1284 if(strncmp(s, "./", 2) == 0) {
1285 trim_string(s, "./", NULL);
1290 while ((p = strstr(s,"/../")) != NULL)
1297 if ((p=strrchr(s,'/')) != NULL)
1304 trim_string(s,NULL,"/..");
1308 /*******************************************************************
1309 a wrapper for the normal chdir() function
1310 ********************************************************************/
1311 int ChDir(char *path)
1314 static pstring LastDir="";
1316 if (strcsequal(path,".")) return(0);
1318 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1319 DEBUG(3,("chdir to %s\n",path));
1320 res = dos_chdir(path);
1322 pstrcpy(LastDir,path);
1326 /* number of list structures for a caching GetWd function. */
1327 #define MAX_GETWDCACHE (50)
1331 SMB_DEV_T dev; /* These *must* be compatible with the types returned in a stat() call. */
1332 SMB_INO_T inode; /* These *must* be compatible with the types returned in a stat() call. */
1333 char *text; /* The pathname in DOS format. */
1335 } ino_list[MAX_GETWDCACHE];
1337 BOOL use_getwd_cache=True;
1339 /*******************************************************************
1340 return the absolute current directory path - given a UNIX pathname.
1341 Note that this path is returned in DOS format, not UNIX
1343 ********************************************************************/
1344 char *GetWd(char *str)
1347 static BOOL getwd_cache_init = False;
1348 SMB_STRUCT_STAT st, st2;
1353 if (!use_getwd_cache)
1354 return(dos_getwd(str));
1356 /* init the cache */
1357 if (!getwd_cache_init)
1359 getwd_cache_init = True;
1360 for (i=0;i<MAX_GETWDCACHE;i++)
1362 string_init(&ino_list[i].text,"");
1363 ino_list[i].valid = False;
1367 /* Get the inode of the current directory, if this doesn't work we're
1370 if (dos_stat(".",&st) == -1)
1372 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1373 return(dos_getwd(str));
1377 for (i=0; i<MAX_GETWDCACHE; i++)
1378 if (ino_list[i].valid)
1381 /* If we have found an entry with a matching inode and dev number
1382 then find the inode number for the directory in the cached string.
1383 If this agrees with that returned by the stat for the current
1384 directory then all is o.k. (but make sure it is a directory all
1387 if (st.st_ino == ino_list[i].inode &&
1388 st.st_dev == ino_list[i].dev)
1390 if (dos_stat(ino_list[i].text,&st2) == 0)
1392 if (st.st_ino == st2.st_ino &&
1393 st.st_dev == st2.st_dev &&
1394 (st2.st_mode & S_IFMT) == S_IFDIR)
1396 pstrcpy (str, ino_list[i].text);
1398 /* promote it for future use */
1399 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1404 /* If the inode is different then something's changed,
1405 scrub the entry and start from scratch. */
1406 ino_list[i].valid = False;
1413 /* We don't have the information to hand so rely on traditional methods.
1414 The very slow getcwd, which spawns a process on some systems, or the
1415 not quite so bad getwd. */
1419 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1425 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1427 /* add it to the cache */
1428 i = MAX_GETWDCACHE - 1;
1429 string_set(&ino_list[i].text,s);
1430 ino_list[i].dev = st.st_dev;
1431 ino_list[i].inode = st.st_ino;
1432 ino_list[i].valid = True;
1434 /* put it at the top of the list */
1435 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1442 /*******************************************************************
1443 reduce a file name, removing .. elements and checking that
1444 it is below dir in the heirachy. This uses GetWd() and so must be run
1445 on the system that has the referenced file system.
1447 widelinks are allowed if widelinks is true
1448 ********************************************************************/
1449 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1451 #ifndef REDUCE_PATHS
1459 BOOL relative = (*s != '/');
1461 *dir2 = *wd = *base_name = *newname = 0;
1466 /* can't have a leading .. */
1467 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1469 DEBUG(3,("Illegal file name? (%s)\n",s));
1479 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1481 /* remove any double slashes */
1482 string_sub(s,"//","/");
1484 pstrcpy(base_name,s);
1485 p = strrchr(base_name,'/');
1492 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1496 if (ChDir(dir) != 0)
1498 DEBUG(0,("couldn't chdir to %s\n",dir));
1504 DEBUG(0,("couldn't getwd for %s\n",dir));
1510 if (p && (p != base_name))
1513 if (strcmp(p+1,".")==0)
1515 if (strcmp(p+1,"..")==0)
1519 if (ChDir(base_name) != 0)
1522 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1526 if (!GetWd(newname))
1529 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1533 if (p && (p != base_name))
1535 pstrcat(newname,"/");
1536 pstrcat(newname,p+1);
1540 int l = strlen(dir2);
1541 if (dir2[l-1] == '/')
1544 if (strncmp(newname,dir2,l) != 0)
1547 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1553 if (newname[l] == '/')
1554 pstrcpy(s,newname + l + 1);
1556 pstrcpy(s,newname+l);
1567 DEBUG(3,("reduced to %s\n",s));
1572 /****************************************************************************
1574 ****************************************************************************/
1575 static void expand_one(char *Mask,int len)
1578 while ((p1 = strchr(Mask,'*')) != NULL)
1580 int lfill = (len+1) - strlen(Mask);
1581 int l1= (p1 - Mask);
1584 memset(tmp+l1,'?',lfill);
1585 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1590 /****************************************************************************
1591 parse out a directory name from a path name. Assumes dos style filenames.
1592 ****************************************************************************/
1593 static char *dirname_dos(char *path,char *buf)
1595 char *p = strrchr(path,'\\');
1610 /****************************************************************************
1611 expand a wildcard expression, replacing *s with ?s
1612 ****************************************************************************/
1613 void expand_mask(char *Mask,BOOL doext)
1618 BOOL hasdot = False;
1620 BOOL absolute = (*Mask == '\\');
1622 *mbeg = *mext = *dirpart = *filepart = 0;
1624 /* parse the directory and filename */
1625 if (strchr(Mask,'\\'))
1626 dirname_dos(Mask,dirpart);
1628 filename_dos(Mask,filepart);
1630 pstrcpy(mbeg,filepart);
1631 if ((p1 = strchr(mbeg,'.')) != NULL)
1641 if (strlen(mbeg) > 8)
1643 pstrcpy(mext,mbeg + 8);
1649 pstrcpy(mbeg,"????????");
1650 if ((*mext == 0) && doext && !hasdot)
1651 pstrcpy(mext,"???");
1653 if (strequal(mbeg,"*") && *mext==0)
1661 pstrcpy(Mask,dirpart);
1662 if (*dirpart || absolute) pstrcat(Mask,"\\");
1667 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1671 /****************************************************************************
1672 does a string have any uppercase chars in it?
1673 ****************************************************************************/
1674 BOOL strhasupper(char *s)
1678 #if !defined(KANJI_WIN95_COMPATIBILITY)
1680 * For completeness we should put in equivalent code for code pages
1681 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1682 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1683 * here. They both treat full width ascii characters as case senstive
1684 * filenames (ie. they don't do the work we do here).
1688 if(lp_client_code_page() == KANJI_CODEPAGE)
1690 /* Win95 treats full width ascii characters as case sensitive. */
1691 if (is_shift_jis (*s))
1693 else if (is_kana (*s))
1703 #endif /* KANJI_WIN95_COMPATIBILITY */
1705 int skip = skip_multibyte_char( *s );
1718 /****************************************************************************
1719 does a string have any lowercase chars in it?
1720 ****************************************************************************/
1721 BOOL strhaslower(char *s)
1725 #if !defined(KANJI_WIN95_COMPATIBILITY)
1727 * For completeness we should put in equivalent code for code pages
1728 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1729 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1730 * here. They both treat full width ascii characters as case senstive
1731 * filenames (ie. they don't do the work we do here).
1735 if(lp_client_code_page() == KANJI_CODEPAGE)
1737 /* Win95 treats full width ascii characters as case sensitive. */
1738 if (is_shift_jis (*s))
1740 if (is_sj_upper (s[0], s[1]))
1742 if (is_sj_lower (s[0], s[1]))
1746 else if (is_kana (*s))
1758 #endif /* KANJI_WIN95_COMPATIBILITY */
1760 int skip = skip_multibyte_char( *s );
1773 /****************************************************************************
1774 find the number of chars in a string
1775 ****************************************************************************/
1776 int count_chars(char *s,char c)
1780 #if !defined(KANJI_WIN95_COMPATIBILITY)
1782 * For completeness we should put in equivalent code for code pages
1783 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1784 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1785 * here. They both treat full width ascii characters as case senstive
1786 * filenames (ie. they don't do the work we do here).
1790 if(lp_client_code_page() == KANJI_CODEPAGE)
1792 /* Win95 treats full width ascii characters as case sensitive. */
1795 if (is_shift_jis (*s))
1806 #endif /* KANJI_WIN95_COMPATIBILITY */
1810 int skip = skip_multibyte_char( *s );
1824 /****************************************************************************
1826 ****************************************************************************/
1827 void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
1832 pstrcpy(mask2,mask);
1834 if ((mode & aDIR) != 0)
1837 memset(buf+1,' ',11);
1838 if ((p = strchr(mask2,'.')) != NULL)
1841 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1842 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1846 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1848 bzero(buf+21,DIR_STRUCT_SIZE-21);
1849 CVAL(buf,21) = mode;
1850 put_dos_date(buf,22,date);
1851 SSVAL(buf,26,size & 0xFFFF);
1852 SSVAL(buf,28,(size >> 16)&0xFFFF);
1853 StrnCpy(buf+30,fname,12);
1854 if (!case_sensitive)
1856 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
1860 /*******************************************************************
1861 close the low 3 fd's and open dev/null in their place
1862 ********************************************************************/
1863 void close_low_fds(void)
1867 close(0); close(1); close(2);
1868 /* try and use up these file descriptors, so silly
1869 library routines writing to stdout etc won't cause havoc */
1871 fd = open("/dev/null",O_RDWR,0);
1872 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
1874 DEBUG(0,("Can't open /dev/null\n"));
1878 DEBUG(0,("Didn't get file descriptor %d\n",i));
1884 /****************************************************************************
1885 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
1887 if SYSV use O_NDELAY
1889 ****************************************************************************/
1890 static int set_blocking(int fd, BOOL set)
1894 #define FLAG_TO_SET O_NONBLOCK
1897 #define FLAG_TO_SET O_NDELAY
1899 #define FLAG_TO_SET FNDELAY
1903 if((val = fcntl(fd, F_GETFL, 0)) == -1)
1905 if(set) /* Turn blocking on - ie. clear nonblock flag */
1906 val &= ~FLAG_TO_SET;
1909 return fcntl( fd, F_SETFL, val);
1914 /****************************************************************************
1916 ****************************************************************************/
1917 ssize_t write_socket(int fd,char *buf,size_t len)
1923 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
1924 ret = write_data(fd,buf,len);
1926 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
1928 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
1929 len, fd, strerror(errno) ));
1934 /****************************************************************************
1936 ****************************************************************************/
1937 ssize_t read_udp_socket(int fd,char *buf,size_t len)
1940 struct sockaddr_in sock;
1943 socklen = sizeof(sock);
1944 bzero((char *)&sock,socklen);
1945 bzero((char *)&lastip,sizeof(lastip));
1946 ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
1948 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
1952 lastip = sock.sin_addr;
1953 lastport = ntohs(sock.sin_port);
1955 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
1956 inet_ntoa(lastip), lastport, ret));
1961 /****************************************************************************
1962 read data from a device with a timout in msec.
1963 mincount = if timeout, minimum to read before returning
1964 maxcount = number to be read.
1965 time_out = timeout in milliseconds
1966 ****************************************************************************/
1968 ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
1974 struct timeval timeout;
1976 /* just checking .... */
1977 if (maxcnt <= 0) return(0);
1982 if (time_out <= 0) {
1983 if (mincnt == 0) mincnt = maxcnt;
1985 while (nread < mincnt) {
1988 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
1990 readret = read(fd, buf + nread, maxcnt - nread);
1992 #else /* WITH_SSL */
1993 readret = read(fd, buf + nread, maxcnt - nread);
1994 #endif /* WITH_SSL */
1997 smb_read_error = READ_EOF;
2001 if (readret == -1) {
2002 smb_read_error = READ_ERROR;
2007 return((ssize_t)nread);
2010 /* Most difficult - timeout read */
2011 /* If this is ever called on a disk file and
2012 mincnt is greater then the filesize then
2013 system performance will suffer severely as
2014 select always returns true on disk files */
2016 /* Set initial timeout */
2017 timeout.tv_sec = (time_t)(time_out / 1000);
2018 timeout.tv_usec = (long)(1000 * (time_out % 1000));
2020 for (nread=0; nread < mincnt; )
2025 selrtn = sys_select(fd+1,&fds,&timeout);
2027 /* Check if error */
2029 /* something is wrong. Maybe the socket is dead? */
2030 smb_read_error = READ_ERROR;
2034 /* Did we timeout ? */
2036 smb_read_error = READ_TIMEOUT;
2042 readret = SSL_read(ssl, buf + nread, maxcnt - nread);
2044 readret = read(fd, buf + nread, maxcnt - nread);
2046 #else /* WITH_SSL */
2047 readret = read(fd, buf+nread, maxcnt-nread);
2048 #endif /* WITH_SSL */
2051 /* we got EOF on the file descriptor */
2052 smb_read_error = READ_EOF;
2056 if (readret == -1) {
2057 /* the descriptor is probably dead */
2058 smb_read_error = READ_ERROR;
2065 /* Return the number we got */
2066 return((ssize_t)nread);
2069 /*******************************************************************
2070 find the difference in milliseconds between two struct timeval
2072 ********************************************************************/
2073 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2075 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2076 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2079 /****************************************************************************
2080 send a keepalive packet (rfc1002)
2081 ****************************************************************************/
2082 BOOL send_keepalive(int client)
2084 unsigned char buf[4];
2087 buf[1] = buf[2] = buf[3] = 0;
2089 return(write_data(client,(char *)buf,4) == 4);
2094 /****************************************************************************
2095 read data from the client, reading exactly N bytes.
2096 ****************************************************************************/
2097 ssize_t read_data(int fd,char *buffer,size_t N)
2108 ret = SSL_read(ssl, buffer + total, N - total);
2110 ret = read(fd,buffer + total,N - total);
2112 #else /* WITH_SSL */
2113 ret = read(fd,buffer + total,N - total);
2114 #endif /* WITH_SSL */
2118 smb_read_error = READ_EOF;
2123 smb_read_error = READ_ERROR;
2128 return (ssize_t)total;
2132 /****************************************************************************
2134 ****************************************************************************/
2135 ssize_t write_data(int fd,char *buffer,size_t N)
2144 ret = SSL_write(ssl,buffer + total,N - total);
2146 ret = write(fd,buffer + total,N - total);
2148 #else /* WITH_SSL */
2149 ret = write(fd,buffer + total,N - total);
2150 #endif /* WITH_SSL */
2152 if (ret == -1) return -1;
2153 if (ret == 0) return total;
2157 return (ssize_t)total;
2161 /****************************************************************************
2162 transfer some data between two fd's
2163 ****************************************************************************/
2164 SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
2166 static char *buf=NULL;
2169 SMB_OFF_T total = 0;
2171 DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
2174 size = lp_readsize();
2175 size = MAX(size,1024);
2178 while (!buf && size>0) {
2179 buf = (char *)Realloc(buf,size+8);
2180 if (!buf) size /= 2;
2184 DEBUG(0,("Can't allocate transfer buffer!\n"));
2188 abuf = buf + (align%8);
2195 int s = (int)MIN(n,(SMB_OFF_T)size);
2200 if (header && (headlen >= MIN(s,1024))) {
2210 if (header && headlen > 0)
2212 ret = MIN(headlen,size);
2213 memcpy(buf1,header,ret);
2216 if (headlen <= 0) header = NULL;
2220 ret += read(infd,buf1+ret,s-ret);
2224 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2225 if (ret2 > 0) total += ret2;
2226 /* if we can't write then dump excess data */
2228 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2230 if (ret <= 0 || ret2 != ret)
2238 /****************************************************************************
2239 read 4 bytes of a smb packet and return the smb length of the packet
2240 store the result in the buffer
2241 This version of the function will return a length of zero on receiving
2243 timeout is in milliseconds.
2244 ****************************************************************************/
2245 static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
2254 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2256 ok = (read_data(fd,inbuf,4) == 4);
2261 len = smb_len(inbuf);
2262 msg_type = CVAL(inbuf,0);
2264 if (msg_type == 0x85)
2265 DEBUG(5,("Got keepalive packet\n"));
2268 DEBUG(10,("got smb length of %d\n",len));
2273 /****************************************************************************
2274 read 4 bytes of a smb packet and return the smb length of the packet
2275 store the result in the buffer. This version of the function will
2276 never return a session keepalive (length of zero).
2277 timeout is in milliseconds.
2278 ****************************************************************************/
2279 ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
2285 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2290 /* Ignore session keepalives. */
2291 if(CVAL(inbuf,0) != 0x85)
2298 /****************************************************************************
2299 read an smb from a fd. Note that the buffer *MUST* be of size
2300 BUFFER_SIZE+SAFETY_MARGIN.
2301 The timeout is in milliseconds.
2302 This function will return on a
2303 receipt of a session keepalive packet.
2304 ****************************************************************************/
2305 BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
2311 bzero(buffer,smb_size + 100);
2313 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2317 if (len > BUFFER_SIZE) {
2318 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2319 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2324 ret = read_data(fd,buffer+4,len);
2326 smb_read_error = READ_ERROR;
2333 /****************************************************************************
2334 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2335 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2336 The timeout is in milliseconds
2338 This is exactly the same as receive_smb except that it never returns
2339 a session keepalive packet (just as receive_smb used to do).
2340 receive_smb was changed to return keepalives as the oplock processing means this call
2341 should never go into a blocking read.
2342 ****************************************************************************/
2344 BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
2350 ret = receive_smb(fd, buffer, timeout);
2357 /* Ignore session keepalive packets. */
2358 if(CVAL(buffer,0) != 0x85)
2364 /****************************************************************************
2366 ****************************************************************************/
2367 BOOL send_smb(int fd,char *buffer)
2372 len = smb_len(buffer) + 4;
2374 while (nwritten < len)
2376 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2379 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2390 /****************************************************************************
2391 find a pointer to a netbios name
2392 ****************************************************************************/
2393 static char *name_ptr(char *buf,int ofs)
2395 unsigned char c = *(unsigned char *)(buf+ofs);
2397 if ((c & 0xC0) == 0xC0)
2401 memcpy(p,buf+ofs,2);
2404 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2411 /****************************************************************************
2412 extract a netbios name from a buf
2413 ****************************************************************************/
2414 int name_extract(char *buf,int ofs,char *name)
2416 char *p = name_ptr(buf,ofs);
2417 int d = PTR_DIFF(p,buf+ofs);
2419 if (d < -50 || d > 50) return(0);
2420 return(name_interpret(p,name));
2423 /****************************************************************************
2424 return the total storage length of a mangled name
2425 ****************************************************************************/
2426 int name_len(char *s1)
2428 /* NOTE: this argument _must_ be unsigned */
2429 unsigned char *s = (unsigned char *)s1;
2432 /* If the two high bits of the byte are set, return 2. */
2433 if (0xC0 == (*s & 0xC0))
2436 /* Add up the length bytes. */
2437 for (len = 1; (*s); s += (*s) + 1) {
2439 SMB_ASSERT(len < 80);
2445 /****************************************************************************
2446 send a single packet to a port on another machine
2447 ****************************************************************************/
2448 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2452 struct sockaddr_in sock_out;
2457 /* create a socket to write to */
2458 out_fd = socket(AF_INET, type, 0);
2461 DEBUG(0,("socket failed"));
2465 /* set the address and port */
2466 bzero((char *)&sock_out,sizeof(sock_out));
2467 putip((char *)&sock_out.sin_addr,(char *)&ip);
2468 sock_out.sin_port = htons( port );
2469 sock_out.sin_family = AF_INET;
2472 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2473 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2476 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2479 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2480 inet_ntoa(ip),port,strerror(errno)));
2486 /*******************************************************************
2487 sleep for a specified number of milliseconds
2488 ********************************************************************/
2492 struct timeval tval,t1,t2;
2499 tval.tv_sec = (t-tdiff)/1000;
2500 tval.tv_usec = 1000*((t-tdiff)%1000);
2504 sys_select(0,&fds,&tval);
2507 tdiff = TvalDiff(&t1,&t2);
2511 /****************************************************************************
2512 check if a string is part of a list
2513 ****************************************************************************/
2514 BOOL in_list(char *s,char *list,BOOL casesensitive)
2519 if (!list) return(False);
2521 while (next_token(&p,tok,LIST_SEP,sizeof(tok))) {
2522 if (casesensitive) {
2523 if (strcmp(tok,s) == 0)
2526 if (StrCaseCmp(tok,s) == 0)
2533 /* this is used to prevent lots of mallocs of size 1 */
2534 static char *null_string = NULL;
2536 /****************************************************************************
2537 set a string value, allocing the space for the string
2538 ****************************************************************************/
2539 BOOL string_init(char **dest,char *src)
2550 if((null_string = (char *)malloc(1)) == NULL) {
2551 DEBUG(0,("string_init: malloc fail for null_string.\n"));
2556 *dest = null_string;
2560 (*dest) = (char *)malloc(l+1);
2561 if ((*dest) == NULL) {
2562 DEBUG(0,("Out of memory in string_init\n"));
2571 /****************************************************************************
2573 ****************************************************************************/
2574 void string_free(char **s)
2576 if (!s || !(*s)) return;
2577 if (*s == null_string)
2583 /****************************************************************************
2584 set a string value, allocing the space for the string, and deallocating any
2586 ****************************************************************************/
2587 BOOL string_set(char **dest,char *src)
2591 return(string_init(dest,src));
2594 /****************************************************************************
2595 substitute a string for a pattern in another string. Make sure there is
2598 This routine looks for pattern in s and replaces it with
2599 insert. It may do multiple replacements.
2601 return True if a substitution was done.
2602 ****************************************************************************/
2603 BOOL string_sub(char *s,char *pattern,char *insert)
2609 if (!insert || !pattern || !s) return(False);
2612 lp = strlen(pattern);
2613 li = strlen(insert);
2615 if (!*pattern) return(False);
2617 while (lp <= ls && (p = strstr(s,pattern)))
2620 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2621 memcpy(p,insert,li);
2628 /*********************************************************
2629 * Recursive routine that is called by unix_mask_match.
2630 * Does the actual matching. This is the 'original code'
2631 * used by the unix matcher.
2632 *********************************************************/
2633 static BOOL unix_do_match(char *str, char *regexp, int case_sig)
2637 for( p = regexp; *p && *str; ) {
2644 /* Look for a character matching
2645 the one after the '*' */
2648 return True; /* Automatic match */
2650 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2652 if(unix_do_match(str,p,case_sig))
2666 if(toupper(*str) != toupper(*p))
2676 if (!*p && str[0] == '.' && str[1] == 0)
2679 if (!*str && *p == '?')
2681 while (*p == '?') p++;
2685 if(!*str && (*p == '*' && p[1] == '\0'))
2691 /*********************************************************
2692 * Routine to match a given string with a regexp - uses
2693 * simplified regexp that takes * and ? only. Case can be
2694 * significant or not.
2695 * This is the 'original code' used by the unix matcher.
2696 *********************************************************/
2698 static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2702 fstring ebase,eext,sbase,sext;
2706 /* Make local copies of str and regexp */
2707 StrnCpy(p1,regexp,sizeof(pstring)-1);
2708 StrnCpy(p2,str,sizeof(pstring)-1);
2710 if (!strchr(p2,'.')) {
2714 /* Remove any *? and ** as they are meaningless */
2715 for(p = p1; *p; p++)
2716 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
2717 (void)pstrcpy( &p[1], &p[2]);
2719 if (strequal(p1,"*")) return(True);
2721 DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
2727 if ((p=strrchr(p1,'.'))) {
2736 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
2746 matched = unix_do_match(sbase,ebase,case_sig) &&
2747 (trans2 || unix_do_match(sext,eext,case_sig));
2749 DEBUG(8,("unix_mask_match returning %d\n", matched));
2754 /*********************************************************
2755 * Recursive routine that is called by mask_match.
2756 * Does the actual matching. Returns True if matched,
2757 * False if failed. This is the 'new' NT style matcher.
2758 *********************************************************/
2760 BOOL do_match(char *str, char *regexp, int case_sig)
2764 for( p = regexp; *p && *str; ) {
2771 /* Look for a character matching
2772 the one after the '*' */
2775 return True; /* Automatic match */
2777 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2779 /* Now eat all characters that match, as
2780 we want the *last* character to match. */
2781 while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str))))
2783 str--; /* We've eaten the match char after the '*' */
2784 if(do_match(str,p,case_sig)) {
2801 if(toupper(*str) != toupper(*p)) {
2813 if (!*p && str[0] == '.' && str[1] == 0) {
2817 if (!*str && *p == '?') {
2823 if(!*str && (*p == '*' && p[1] == '\0')) {
2831 /*********************************************************
2832 * Routine to match a given string with a regexp - uses
2833 * simplified regexp that takes * and ? only. Case can be
2834 * significant or not.
2835 * The 8.3 handling was rewritten by Ums Harald <Harald.Ums@pro-sieben.de>
2836 * This is the new 'NT style' matcher.
2837 *********************************************************/
2839 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
2842 pstring t_pattern, t_filename, te_pattern, te_filename;
2843 fstring ebase,eext,sbase,sext;
2845 BOOL matched = False;
2847 /* Make local copies of str and regexp */
2848 pstrcpy(t_pattern,regexp);
2849 pstrcpy(t_filename,str);
2853 * Not sure if this is a good idea. JRA.
2855 if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
2860 if (!strchr(t_filename,'.')) {
2861 pstrcat(t_filename,".");
2865 /* Remove any *? and ** as they are meaningless */
2866 string_sub(t_pattern, "*?", "*");
2867 string_sub(t_pattern, "**", "*");
2869 if (strequal(t_pattern,"*"))
2872 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
2876 * Match each component of the regexp, split up by '.'
2879 char *fp, *rp, *cp2, *cp1;
2880 BOOL last_wcard_was_star = False;
2881 int num_path_components, num_regexp_components;
2883 pstrcpy(te_pattern,t_pattern);
2884 pstrcpy(te_filename,t_filename);
2886 * Remove multiple "*." patterns.
2888 string_sub(te_pattern, "*.*.", "*.");
2889 num_regexp_components = count_chars(te_pattern, '.');
2890 num_path_components = count_chars(te_filename, '.');
2893 * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
2895 if(num_regexp_components == 0)
2896 matched = do_match( te_filename, te_pattern, case_sig);
2898 for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
2899 fp = strchr(cp2, '.');
2902 rp = strchr(cp1, '.');
2906 if(cp1[strlen(cp1)-1] == '*')
2907 last_wcard_was_star = True;
2909 last_wcard_was_star = False;
2911 if(!do_match(cp2, cp1, case_sig))
2914 cp1 = rp ? rp + 1 : NULL;
2915 cp2 = fp ? fp + 1 : "";
2917 if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
2918 /* Eat the extra path components. */
2921 for(i = 0; i < num_path_components - num_regexp_components; i++) {
2922 fp = strchr(cp2, '.');
2926 if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) {
2927 cp2 = fp ? fp + 1 : "";
2930 cp2 = fp ? fp + 1 : "";
2932 num_path_components -= i;
2935 if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
2940 /* -------------------------------------------------
2941 * Behaviour of Win95
2942 * for 8.3 filenames and 8.3 Wildcards
2943 * -------------------------------------------------
2945 if (strequal (t_filename, ".")) {
2947 * Patterns: *.* *. ?. ? are valid
2950 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2951 strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
2953 } else if (strequal (t_filename, "..")) {
2955 * Patterns: *.* *. ?. ? *.? are valid
2958 if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
2959 strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
2960 strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
2964 if ((p = strrchr (t_pattern, '.'))) {
2966 * Wildcard has a suffix.
2969 fstrcpy (ebase, t_pattern);
2971 fstrcpy (eext, p + 1);
2973 /* pattern ends in DOT: treat as if there is no DOT */
2975 if (strequal (ebase, "*"))
2980 * No suffix for wildcard.
2982 fstrcpy (ebase, t_pattern);
2986 p = strrchr (t_filename, '.');
2987 if (p && (p[1] == 0) ) {
2989 * Filename has an extension of '.' only.
2991 *p = 0; /* nuke dot at end of string */
2992 p = 0; /* and treat it as if there is no extension */
2997 * Filename has an extension.
3000 fstrcpy (sbase, t_filename);
3001 fstrcpy (sext, p + 1);
3003 matched = do_match(sbase, ebase, case_sig)
3004 && do_match(sext, eext, case_sig);
3006 /* pattern has no extension */
3007 /* Really: match complete filename with pattern ??? means exactly 3 chars */
3008 matched = do_match(str, ebase, case_sig);
3012 * Filename has no extension.
3014 fstrcpy (sbase, t_filename);
3017 /* pattern has extension */
3018 matched = do_match(sbase, ebase, case_sig)
3019 && do_match(sext, eext, case_sig);
3021 matched = do_match(sbase, ebase, case_sig);
3022 #ifdef EMULATE_WEIRD_W95_MATCHING
3024 * Even Microsoft has some problems
3025 * Behaviour Win95 -> local disk
3026 * is different from Win95 -> smb drive from Nt 4.0
3027 * This branch would reflect the Win95 local disk behaviour
3030 /* a? matches aa and a in w95 */
3031 fstrcat (sbase, ".");
3032 matched = do_match(sbase, ebase, case_sig);
3040 DEBUG(8,("mask_match returning %d\n", matched));
3045 /****************************************************************************
3046 become a daemon, discarding the controlling terminal
3047 ****************************************************************************/
3048 void become_daemon(void)
3054 /* detach from the terminal */
3057 #elif defined(TIOCNOTTY)
3059 int i = open("/dev/tty", O_RDWR);
3061 ioctl(i, (int) TIOCNOTTY, (char *)0);
3065 #endif /* HAVE_SETSID */
3067 /* Close fd's 0,1,2. Needed if started by rsh */
3072 /****************************************************************************
3073 put up a yes/no prompt
3074 ****************************************************************************/
3080 if (!fgets(ans,sizeof(ans)-1,stdin))
3083 if (*ans == 'y' || *ans == 'Y')
3089 /****************************************************************************
3090 read a line from a file with possible \ continuation chars.
3091 Blanks at the start or end of a line are stripped.
3092 The string will be allocated if s2 is NULL
3093 ****************************************************************************/
3094 char *fgets_slash(char *s2,int maxlen,FILE *f)
3099 BOOL start_of_line = True;
3106 maxlen = MIN(maxlen,8);
3107 s = (char *)Realloc(s,maxlen);
3110 if (!s || maxlen < 2) return(NULL);
3114 while (len < maxlen-1)
3122 while (len > 0 && s[len-1] == ' ')
3126 if (len > 0 && s[len-1] == '\\')
3129 start_of_line = True;
3134 if (len <= 0 && !s2)
3136 return(len>0?s:NULL);
3141 start_of_line = False;
3145 if (!s2 && len > maxlen-3)
3148 s = (char *)Realloc(s,maxlen);
3149 if (!s) return(NULL);
3157 /****************************************************************************
3158 set the length of a file from a filedescriptor.
3159 Returns 0 on success, -1 on failure.
3160 ****************************************************************************/
3161 int set_filelen(int fd, SMB_OFF_T len)
3163 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3164 extend a file with ftruncate. Provide alternate implementation
3167 #ifdef HAVE_FTRUNCATE_EXTEND
3168 return sys_ftruncate(fd, len);
3172 SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
3176 /* Do an fstat to see if the file is longer than
3177 the requested size (call ftruncate),
3178 or shorter, in which case seek to len - 1 and write 1
3180 if(sys_fstat(fd, &st)<0)
3184 if (S_ISFIFO(st.st_mode)) return 0;
3187 if(st.st_size == len)
3189 if(st.st_size > len)
3190 return sys_ftruncate(fd, len);
3192 if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
3194 if(write(fd, &c, 1)!=1)
3196 /* Seek to where we were */
3197 if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
3205 /****************************************************************************
3206 this is a version of setbuffer() for those machines that only have setvbuf
3207 ****************************************************************************/
3208 void setbuffer(FILE *f,char *buf,int bufsize)
3210 setvbuf(f,buf,_IOFBF,bufsize);
3215 /****************************************************************************
3216 parse out a filename from a path name. Assumes dos style filenames.
3217 ****************************************************************************/
3218 static char *filename_dos(char *path,char *buf)
3220 char *p = strrchr(path,'\\');
3232 /****************************************************************************
3233 expand a pointer to be a particular size
3234 ****************************************************************************/
3235 void *Realloc(void *p,size_t size)
3241 DEBUG(5,("Realloc asked for 0 bytes\n"));
3246 ret = (void *)malloc(size);
3248 ret = (void *)realloc(p,size);
3251 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3257 /****************************************************************************
3258 get my own name and IP
3259 ****************************************************************************/
3260 BOOL get_myname(char *my_name,struct in_addr *ip)
3267 /* get my host name */
3268 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3270 DEBUG(0,("gethostname failed\n"));
3275 if ((hp = Get_Hostbyname(hostname)) == 0)
3277 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3283 /* split off any parts after an initial . */
3284 char *p = strchr(hostname,'.');
3287 fstrcpy(my_name,hostname);
3291 putip((char *)ip,(char *)hp->h_addr);
3297 /****************************************************************************
3298 true if two IP addresses are equal
3299 ****************************************************************************/
3300 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3303 a1 = ntohl(ip1.s_addr);
3304 a2 = ntohl(ip2.s_addr);
3309 /****************************************************************************
3310 open a socket of the specified type, port and address for incoming data
3311 ****************************************************************************/
3312 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3315 struct sockaddr_in sock;
3319 /* get my host name */
3320 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3321 { DEBUG(0,("gethostname failed\n")); return -1; }
3324 if ((hp = Get_Hostbyname(host_name)) == 0)
3326 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3330 bzero((char *)&sock,sizeof(sock));
3331 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3333 #ifdef HAVE_SOCK_SIN_LEN
3334 sock.sin_len = sizeof(sock);
3336 sock.sin_port = htons( port );
3337 sock.sin_family = hp->h_addrtype;
3338 sock.sin_addr.s_addr = socket_addr;
3339 res = socket(hp->h_addrtype, type, 0);
3341 { DEBUG(0,("socket failed\n")); return -1; }
3345 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3348 /* now we've got a socket - we need to bind it */
3349 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3352 if (port == SMB_PORT || port == NMB_PORT)
3353 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3354 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3357 if (dlevel > 0 && port < 1000)
3360 if (port >= 1000 && port < 9000)
3361 return(open_socket_in(type,port+1,dlevel,socket_addr));
3366 DEBUG(3,("bind succeeded on port %d\n",port));
3372 /****************************************************************************
3373 create an outgoing socket
3374 **************************************************************************/
3375 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3377 struct sockaddr_in sock_out;
3379 int connect_loop = 250; /* 250 milliseconds */
3380 int loops = (timeout * 1000) / connect_loop;
3382 /* create a socket to write to */
3383 res = socket(PF_INET, type, 0);
3385 { DEBUG(0,("socket error\n")); return -1; }
3387 if (type != SOCK_STREAM) return(res);
3389 bzero((char *)&sock_out,sizeof(sock_out));
3390 putip((char *)&sock_out.sin_addr,(char *)addr);
3392 sock_out.sin_port = htons( port );
3393 sock_out.sin_family = PF_INET;
3395 /* set it non-blocking */
3396 set_blocking(res,False);
3398 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3400 /* and connect it to the destination */
3402 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3404 /* Some systems return EAGAIN when they mean EINPROGRESS */
3405 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3406 errno == EAGAIN) && loops--) {
3407 msleep(connect_loop);
3411 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3413 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3419 if (ret < 0 && errno == EISCONN) {
3426 DEBUG(1,("error connecting to %s:%d (%s)\n",
3427 inet_ntoa(*addr),port,strerror(errno)));
3432 /* set it blocking again */
3433 set_blocking(res,True);
3439 /****************************************************************************
3440 interpret a protocol description string, with a default
3441 ****************************************************************************/
3442 int interpret_protocol(char *str,int def)
3444 if (strequal(str,"NT1"))
3445 return(PROTOCOL_NT1);
3446 if (strequal(str,"LANMAN2"))
3447 return(PROTOCOL_LANMAN2);
3448 if (strequal(str,"LANMAN1"))
3449 return(PROTOCOL_LANMAN1);
3450 if (strequal(str,"CORE"))
3451 return(PROTOCOL_CORE);
3452 if (strequal(str,"COREPLUS"))
3453 return(PROTOCOL_COREPLUS);
3454 if (strequal(str,"CORE+"))
3455 return(PROTOCOL_COREPLUS);
3457 DEBUG(0,("Unrecognised protocol level %s\n",str));
3463 /****************************************************************************
3464 interpret an internet address or name into an IP address in 4 byte form
3465 ****************************************************************************/
3466 uint32 interpret_addr(char *str)
3471 BOOL pure_address = True;
3473 if (strcmp(str,"0.0.0.0") == 0) return(0);
3474 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3476 for (i=0; pure_address && str[i]; i++)
3477 if (!(isdigit((int)str[i]) || str[i] == '.'))
3478 pure_address = False;
3480 /* if it's in the form of an IP address then get the lib to interpret it */
3482 res = inet_addr(str);
3484 /* otherwise assume it's a network name of some sort and use
3486 if ((hp = Get_Hostbyname(str)) == 0) {
3487 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3490 if(hp->h_addr == NULL) {
3491 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3494 putip((char *)&res,(char *)hp->h_addr);
3497 if (res == (uint32)-1) return(0);
3502 /*******************************************************************
3503 a convenient addition to interpret_addr()
3504 ******************************************************************/
3505 struct in_addr *interpret_addr2(char *str)
3507 static struct in_addr ret;
3508 uint32 a = interpret_addr(str);
3513 /*******************************************************************
3514 check if an IP is the 0.0.0.0
3515 ******************************************************************/
3516 BOOL zero_ip(struct in_addr ip)
3519 putip((char *)&a,(char *)&ip);
3524 /*******************************************************************
3525 matchname - determine if host name matches IP address
3526 ******************************************************************/
3527 static BOOL matchname(char *remotehost,struct in_addr addr)
3532 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3533 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3538 * Make sure that gethostbyname() returns the "correct" host name.
3539 * Unfortunately, gethostbyname("localhost") sometimes yields
3540 * "localhost.domain". Since the latter host name comes from the
3541 * local DNS, we just have to trust it (all bets are off if the local
3542 * DNS is perverted). We always check the address list, though.
3545 if (strcasecmp(remotehost, hp->h_name)
3546 && strcasecmp(remotehost, "localhost")) {
3547 DEBUG(0,("host name/name mismatch: %s != %s",
3548 remotehost, hp->h_name));
3552 /* Look up the host address in the address list we just got. */
3553 for (i = 0; hp->h_addr_list[i]; i++) {
3554 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3559 * The host name does not map to the original host address. Perhaps
3560 * someone has compromised a name server. More likely someone botched
3561 * it, but that could be dangerous, too.
3564 DEBUG(0,("host name/address mismatch: %s != %s",
3565 inet_ntoa(addr), hp->h_name));
3569 /*******************************************************************
3570 Reset the 'done' variables so after a client process is created
3571 from a fork call these calls will be re-done. This should be
3572 expanded if more variables need reseting.
3573 ******************************************************************/
3575 static BOOL global_client_name_done = False;
3576 static BOOL global_client_addr_done = False;
3578 void reset_globals_after_fork(void)
3580 global_client_name_done = False;
3581 global_client_addr_done = False;
3584 * Re-seed the random crypto generator, so all smbd's
3585 * started from the same parent won't generate the same
3589 unsigned char dummy;
3590 generate_random_buffer( &dummy, 1, True);
3594 /*******************************************************************
3595 return the DNS name of the client
3596 ******************************************************************/
3597 char *client_name(int fd)
3600 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3601 int length = sizeof(sa);
3602 static pstring name_buf;
3604 static int last_fd=-1;
3606 if (global_client_name_done && last_fd == fd)
3610 global_client_name_done = False;
3612 pstrcpy(name_buf,"UNKNOWN");
3618 if (getpeername(fd, &sa, &length) < 0) {
3619 DEBUG(0,("getpeername failed\n"));
3623 /* Look up the remote host name. */
3624 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3625 sizeof(sockin->sin_addr),
3627 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3628 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3630 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3631 if (!matchname(name_buf, sockin->sin_addr)) {
3632 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3633 pstrcpy(name_buf,"UNKNOWN");
3636 global_client_name_done = True;
3640 /*******************************************************************
3641 return the IP addr of the client as a string
3642 ******************************************************************/
3643 char *client_addr(int fd)
3646 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3647 int length = sizeof(sa);
3648 static fstring addr_buf;
3649 static int last_fd = -1;
3651 if (global_client_addr_done && fd == last_fd)
3655 global_client_addr_done = False;
3657 fstrcpy(addr_buf,"0.0.0.0");
3663 if (getpeername(fd, &sa, &length) < 0) {
3664 DEBUG(0,("getpeername failed\n"));
3668 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3670 global_client_addr_done = True;
3674 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
3675 /******************************************************************
3676 Remove any mount options such as -rsize=2048,wsize=2048 etc.
3677 Based on a fix from <Thomas.Hepper@icem.de>.
3678 *******************************************************************/
3680 static void strip_mount_options( pstring *str)
3685 while(*p && !isspace(*p))
3687 while(*p && isspace(*p))
3692 pstrcpy(tmp_str, p);
3693 pstrcpy(*str, tmp_str);
3698 /*******************************************************************
3699 Patch from jkf@soton.ac.uk
3700 Split Luke's automount_server into YP lookup and string splitter
3701 so can easily implement automount_path().
3702 As we may end up doing both, cache the last YP result.
3703 *******************************************************************/
3705 #ifdef WITH_NISPLUS_HOME
3706 static char *automount_lookup(char *user_name)
3708 static fstring last_key = "";
3709 static pstring last_value = "";
3711 char *nis_map = (char *)lp_nis_home_map_name();
3713 char nis_domain[NIS_MAXNAMELEN + 1];
3714 char buffer[NIS_MAXATTRVAL + 1];
3719 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3720 nis_domain[NIS_MAXNAMELEN] = '\0';
3722 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3724 if (strcmp(user_name, last_key))
3726 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3727 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3729 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3731 if (result->status != NIS_SUCCESS)
3733 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3734 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3738 object = result->objects.objects_val;
3739 if (object->zo_data.zo_type == ENTRY_OBJ)
3741 entry = &object->zo_data.objdata_u.en_data;
3742 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3743 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3745 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3746 string_sub(last_value, "&", user_name);
3747 fstrcpy(last_key, user_name);
3751 nis_freeresult(result);
3754 strip_mount_options(&last_value);
3756 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3759 #else /* WITH_NISPLUS_HOME */
3760 static char *automount_lookup(char *user_name)
3762 static fstring last_key = "";
3763 static pstring last_value = "";
3765 int nis_error; /* returned by yp all functions */
3766 char *nis_result; /* yp_match inits this */
3767 int nis_result_len; /* and set this */
3768 char *nis_domain; /* yp_get_default_domain inits this */
3769 char *nis_map = (char *)lp_nis_home_map_name();
3771 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3773 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3777 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3779 if (!strcmp(user_name, last_key))
3781 nis_result = last_value;
3782 nis_result_len = strlen(last_value);
3787 if ((nis_error = yp_match(nis_domain, nis_map,
3788 user_name, strlen(user_name),
3789 &nis_result, &nis_result_len)) != 0)
3791 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3792 yperr_string(nis_error), user_name, nis_map));
3794 if (!nis_error && nis_result_len >= sizeof(pstring))
3796 nis_result_len = sizeof(pstring)-1;
3798 fstrcpy(last_key, user_name);
3799 strncpy(last_value, nis_result, nis_result_len);
3800 last_value[nis_result_len] = '\0';
3803 strip_mount_options(&last_value);
3805 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3808 #endif /* WITH_NISPLUS_HOME */
3811 /*******************************************************************
3812 Patch from jkf@soton.ac.uk
3813 This is Luke's original function with the NIS lookup code
3814 moved out to a separate function.
3815 *******************************************************************/
3816 static char *automount_server(char *user_name)
3818 static pstring server_name;
3820 /* use the local machine name as the default */
3821 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3822 pstrcpy(server_name, local_machine);
3824 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3826 if (lp_nis_home_map())
3828 int home_server_len;
3829 char *automount_value = automount_lookup(user_name);
3830 home_server_len = strcspn(automount_value,":");
3831 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3832 if (home_server_len > sizeof(pstring))
3834 home_server_len = sizeof(pstring);
3836 strncpy(server_name, automount_value, home_server_len);
3837 server_name[home_server_len] = '\0';
3841 DEBUG(4,("Home server: %s\n", server_name));
3846 /*******************************************************************
3847 Patch from jkf@soton.ac.uk
3848 Added this to implement %p (NIS auto-map version of %H)
3849 *******************************************************************/
3850 static char *automount_path(char *user_name)
3852 static pstring server_path;
3854 /* use the passwd entry as the default */
3855 /* this will be the default if WITH_AUTOMOUNT is not used or fails */
3856 /* pstrcpy() copes with get_home_dir() returning NULL */
3857 pstrcpy(server_path, get_home_dir(user_name));
3859 #if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
3861 if (lp_nis_home_map())
3863 char *home_path_start;
3864 char *automount_value = automount_lookup(user_name);
3865 home_path_start = strchr(automount_value,':');
3866 if (home_path_start != NULL)
3868 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
3869 home_path_start?(home_path_start+1):""));
3870 pstrcpy(server_path, home_path_start+1);
3875 DEBUG(4,("Home server path: %s\n", server_path));
3881 /*******************************************************************
3882 sub strings with useful parameters
3883 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
3884 Paul Rippin <pr3245@nopc.eurostat.cec.be>
3885 ********************************************************************/
3886 void standard_sub_basic(char *str)
3890 struct passwd *pass;
3891 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
3893 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
3899 if ((pass = Get_Pwnam(username,False))!=NULL)
3901 string_sub(p,"%G",gidtoname(pass->pw_gid));
3909 case 'N' : string_sub(p,"%N", automount_server(username)); break;
3910 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
3911 case 'L' : string_sub(p,"%L", local_machine); break;
3912 case 'M' : string_sub(p,"%M", client_name(Client)); break;
3913 case 'R' : string_sub(p,"%R", remote_proto); break;
3914 case 'T' : string_sub(p,"%T", timestring()); break;
3915 case 'U' : string_sub(p,"%U", username); break;
3916 case 'a' : string_sub(p,"%a", remote_arch); break;
3919 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
3920 string_sub(p,"%d", pidstr);
3923 case 'h' : string_sub(p,"%h", myhostname); break;
3924 case 'm' : string_sub(p,"%m", remote_machine); break;
3925 case 'v' : string_sub(p,"%v", VERSION); break;
3926 case '$' : /* Expand environment variables */
3928 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
3939 if ((q = strchr(p,')')) == NULL)
3941 DEBUG(0,("standard_sub_basic: Unterminated environment \
3942 variable [%s]\n", p));
3948 copylen = MIN((q-r),(sizeof(envname)-1));
3949 strncpy(envname,r,copylen);
3950 envname[copylen] = '\0';
3952 if ((envval = getenv(envname)) == NULL)
3954 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
3960 copylen = MIN((q+1-p),(sizeof(envname)-1));
3961 strncpy(envname,p,copylen);
3962 envname[copylen] = '\0';
3963 string_sub(p,envname,envval);
3966 case '\0': p++; break; /* don't run off end if last character is % */
3967 default : p+=2; break;
3974 /****************************************************************************
3975 do some standard substitutions in a string
3976 ****************************************************************************/
3977 void standard_sub(connection_struct *conn,char *str)
3981 for (s=str; (p=strchr(s, '%'));s=p) {
3984 if ((home = get_home_dir(conn->user))) {
3985 string_sub(p,"%H",home);
3992 string_sub(p,"%P",conn->connectpath);
3997 lp_servicename(SNUM(conn)));
4002 gidtoname(conn->gid));
4005 string_sub(p,"%u",conn->user);
4008 /* Patch from jkf@soton.ac.uk Left the %N (NIS
4009 * server name) in standard_sub_basic as it is
4010 * a feature for logon servers, hence uses the
4011 * username. The %p (NIS server path) code is
4012 * here as it is used instead of the default
4013 * "path =" string in [homes] and so needs the
4014 * service name, not the username. */
4017 automount_path(lp_servicename(SNUM(conn))));
4021 break; /* don't run off the end of the string
4029 standard_sub_basic(str);
4034 /*******************************************************************
4035 are two IPs on the same subnet?
4036 ********************************************************************/
4037 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4039 uint32 net1,net2,nmask;
4041 nmask = ntohl(mask.s_addr);
4042 net1 = ntohl(ip1.s_addr);
4043 net2 = ntohl(ip2.s_addr);
4045 return((net1 & nmask) == (net2 & nmask));
4049 /*******************************************************************
4050 write a string in unicoode format
4051 ********************************************************************/
4052 int PutUniCode(char *dst,char *src)
4056 dst[ret++] = src[0];
4065 /****************************************************************************
4066 a wrapper for gethostbyname() that tries with all lower and all upper case
4067 if the initial name fails
4068 ****************************************************************************/
4069 struct hostent *Get_Hostbyname(char *name)
4071 char *name2 = strdup(name);
4072 struct hostent *ret;
4076 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4082 * This next test is redundent and causes some systems (with
4083 * broken isalnum() calls) problems.
4088 if (!isalnum(*name2))
4095 ret = sys_gethostbyname(name2);
4102 /* try with all lowercase */
4104 ret = sys_gethostbyname(name2);
4111 /* try with all uppercase */
4113 ret = sys_gethostbyname(name2);
4120 /* nothing works :-( */
4126 /****************************************************************************
4127 check if a process exists. Does this work on all unixes?
4128 ****************************************************************************/
4130 BOOL process_exists(int pid)
4132 return(kill(pid,0) == 0 || errno != ESRCH);
4136 /*******************************************************************
4137 turn a uid into a user name
4138 ********************************************************************/
4139 char *uidtoname(uid_t uid)
4141 static char name[40];
4142 struct passwd *pass = getpwuid(uid);
4143 if (pass) return(pass->pw_name);
4144 slprintf(name, sizeof(name) - 1, "%d",(int)uid);
4149 /*******************************************************************
4150 turn a gid into a group name
4151 ********************************************************************/
4153 char *gidtoname(gid_t gid)
4155 static char name[40];
4156 struct group *grp = getgrgid(gid);
4157 if (grp) return(grp->gr_name);
4158 slprintf(name,sizeof(name) - 1, "%d",(int)gid);
4162 /*******************************************************************
4163 turn a user name into a uid
4164 ********************************************************************/
4165 uid_t nametouid(const char *name)
4167 struct passwd *pass = getpwnam(name);
4168 if (pass) return(pass->pw_uid);
4172 /*******************************************************************
4173 something really nasty happened - panic!
4174 ********************************************************************/
4175 void smb_panic(char *why)
4177 char *cmd = lp_panic_action();
4181 DEBUG(0,("PANIC: %s\n", why));
4186 /*******************************************************************
4187 a readdir wrapper which just returns the file name
4188 ********************************************************************/
4189 char *readdirname(void *p)
4194 if (!p) return(NULL);
4196 ptr = (struct dirent *)readdir(p);
4197 if (!ptr) return(NULL);
4199 dname = ptr->d_name;
4202 if (telldir(p) < 0) return(NULL);
4205 #ifdef HAVE_BROKEN_READDIR
4206 /* using /usr/ucb/cc is BAD */
4212 memcpy(buf, dname, NAMLEN(ptr)+1);
4213 unix_to_dos(buf, True);
4220 /*******************************************************************
4221 Utility function used to decide if the last component
4222 of a path matches a (possibly wildcarded) entry in a namelist.
4223 ********************************************************************/
4225 BOOL is_in_path(char *name, name_compare_entry *namelist)
4227 pstring last_component;
4230 DEBUG(8, ("is_in_path: %s\n", name));
4232 /* if we have no list it's obviously not in the path */
4233 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4235 DEBUG(8,("is_in_path: no name list.\n"));
4239 /* Get the last component of the unix name. */
4240 p = strrchr(name, '/');
4241 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4242 last_component[sizeof(last_component)-1] = '\0';
4244 for(; namelist->name != NULL; namelist++)
4246 if(namelist->is_wild)
4249 * Look for a wildcard match. Use the old
4250 * 'unix style' mask match, rather than the
4253 if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
4255 DEBUG(8,("is_in_path: mask match succeeded\n"));
4261 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4262 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4264 DEBUG(8,("is_in_path: match succeeded\n"));
4269 DEBUG(8,("is_in_path: match not found\n"));
4274 /*******************************************************************
4275 Strip a '/' separated list into an array of
4276 name_compare_enties structures suitable for
4277 passing to is_in_path(). We do this for
4278 speed so we can pre-parse all the names in the list
4279 and don't do it for each call to is_in_path().
4280 namelist is modified here and is assumed to be
4281 a copy owned by the caller.
4282 We also check if the entry contains a wildcard to
4283 remove a potentially expensive call to mask_match
4285 ********************************************************************/
4287 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4290 char *nameptr = namelist;
4291 int num_entries = 0;
4294 (*ppname_array) = NULL;
4296 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4299 /* We need to make two passes over the string. The
4300 first to count the number of elements, the second
4305 if ( *nameptr == '/' )
4307 /* cope with multiple (useless) /s) */
4311 /* find the next / */
4312 name_end = strchr(nameptr, '/');
4314 /* oops - the last check for a / didn't find one. */
4315 if (name_end == NULL)
4318 /* next segment please */
4319 nameptr = name_end + 1;
4323 if(num_entries == 0)
4326 if(( (*ppname_array) = (name_compare_entry *)malloc(
4327 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4329 DEBUG(0,("set_namearray: malloc fail\n"));
4333 /* Now copy out the names */
4338 if ( *nameptr == '/' )
4340 /* cope with multiple (useless) /s) */
4344 /* find the next / */
4345 if ((name_end = strchr(nameptr, '/')) != NULL)
4350 /* oops - the last check for a / didn't find one. */
4351 if(name_end == NULL)
4354 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4355 (strchr( nameptr, '*')!=NULL));
4356 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4358 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4362 /* next segment please */
4363 nameptr = name_end + 1;
4367 (*ppname_array)[i].name = NULL;
4372 /****************************************************************************
4373 routine to free a namearray.
4374 ****************************************************************************/
4376 void free_namearray(name_compare_entry *name_array)
4381 if(name_array->name != NULL)
4382 free(name_array->name);
4384 free((char *)name_array);
4387 /****************************************************************************
4388 routine to do file locking
4389 ****************************************************************************/
4390 BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
4393 SMB_STRUCT_FLOCK lock;
4396 if(lp_ole_locking_compat()) {
4397 SMB_OFF_T mask = ((SMB_OFF_T)0xC) << (SMB_OFF_T_BITS-4);
4398 SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
4400 /* make sure the count is reasonable, we might kill the lockd otherwise */
4403 /* the offset is often strange - remove 2 of its bits if either of
4404 the top two bits are set. Shift the top ones by two bits. This
4405 still allows OLE2 apps to operate, but should stop lockd from
4407 if ((offset & mask) != 0)
4408 offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
4410 SMB_OFF_T mask = ((SMB_OFF_T)0x8) << (SMB_OFF_T_BITS-4);
4411 SMB_OFF_T neg_mask = ~mask;
4413 /* interpret negative counts as large numbers */
4417 /* no negative offsets */
4421 /* count + offset must be in range */
4422 while ((offset < 0 || (offset + count < 0)) && mask)
4425 mask = ((mask >> 1) & neg_mask);
4429 DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
4432 lock.l_whence = SEEK_SET;
4433 lock.l_start = offset;
4439 ret = fcntl(fd,op,&lock);
4444 dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
4445 dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
4446 dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
4448 /* 32 bit NFS file system, retry with smaller offset */
4450 lock.l_len = count & 0xffffffff;
4451 ret = fcntl(fd,op,&lock);
4455 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4458 if (op == SMB_F_GETLK)
4461 (lock.l_type != F_UNLCK) &&
4462 (lock.l_pid != 0) &&
4463 (lock.l_pid != getpid()))
4465 DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
4469 /* it must be not locked or locked by me */
4473 /* a lock set or unset */
4476 DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
4477 (double)offset,(double)count,op,type,strerror(errno)));
4479 /* perhaps it doesn't support this sort of locking?? */
4480 if (errno == EINVAL)
4482 DEBUG(3,("locking not supported? returning True\n"));
4489 /* everything went OK */
4490 DEBUG(8,("Lock call successful\n"));
4498 /*******************************************************************
4499 is the name specified one of my netbios names
4500 returns true is it is equal, false otherwise
4501 ********************************************************************/
4502 BOOL is_myname(char *s)
4507 for (n=0; my_netbios_names[n]; n++) {
4508 if (strequal(my_netbios_names[n], s))
4511 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4515 /*******************************************************************
4516 set the horrid remote_arch string based on an enum.
4517 ********************************************************************/
4518 void set_remote_arch(enum remote_arch_types type)
4524 fstrcpy(remote_arch, "WfWg");
4527 fstrcpy(remote_arch, "OS2");
4530 fstrcpy(remote_arch, "Win95");
4533 fstrcpy(remote_arch, "WinNT");
4536 fstrcpy(remote_arch,"Samba");
4539 ra_type = RA_UNKNOWN;
4540 fstrcpy(remote_arch, "UNKNOWN");
4545 /*******************************************************************
4546 Get the remote_arch type.
4547 ********************************************************************/
4548 enum remote_arch_types get_remote_arch(void)
4554 /*******************************************************************
4555 skip past some unicode strings in a buffer
4556 ********************************************************************/
4557 char *skip_unicode_string(char *buf,int n)
4568 /*******************************************************************
4569 Return a ascii version of a unicode string
4570 Hack alert: uses fixed buffer(s) and only handles ascii strings
4571 ********************************************************************/
4573 char *unistrn2(uint16 *buf, int len)
4575 static char lbufs[8][MAXUNI];
4577 char *lbuf = lbufs[nexti];
4580 nexti = (nexti+1)%8;
4582 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4591 /*******************************************************************
4592 Return a ascii version of a unicode string
4593 Hack alert: uses fixed buffer(s) and only handles ascii strings
4594 ********************************************************************/
4596 char *unistr2(uint16 *buf)
4598 static char lbufs[8][MAXUNI];
4600 char *lbuf = lbufs[nexti];
4603 nexti = (nexti+1)%8;
4605 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4614 /*******************************************************************
4615 create a null-terminated unicode string from a null-terminated ascii string.
4616 return number of unicode chars copied, excluding the null character.
4618 only handles ascii strings
4619 ********************************************************************/
4621 int struni2(uint16 *p, char *buf)
4625 if (p == NULL) return 0;
4629 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4640 /*******************************************************************
4641 Return a ascii version of a unicode string
4642 Hack alert: uses fixed buffer(s) and only handles ascii strings
4643 ********************************************************************/
4645 char *unistr(char *buf)
4647 static char lbufs[8][MAXUNI];
4649 char *lbuf = lbufs[nexti];
4652 nexti = (nexti+1)%8;
4654 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4663 /*******************************************************************
4664 strcpy for unicode strings. returns length (in num of wide chars)
4665 ********************************************************************/
4666 int unistrcpy(char *dst, char *src)
4682 /*******************************************************************
4683 safe string copy into a known length string. maxlength does not
4684 include the terminating zero.
4685 ********************************************************************/
4686 char *safe_strcpy(char *dest,const char *src, int maxlength)
4691 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4702 if (len > maxlength) {
4703 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4704 len-maxlength, src));
4708 memcpy(dest, src, len);
4713 /*******************************************************************
4714 safe string cat into a string. maxlength does not
4715 include the terminating zero.
4716 ********************************************************************/
4717 char *safe_strcat(char *dest, char *src, int maxlength)
4719 int src_len, dest_len;
4722 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4730 src_len = strlen(src);
4731 dest_len = strlen(dest);
4733 if (src_len + dest_len > maxlength) {
4734 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4735 src_len + dest_len - maxlength, src));
4736 src_len = maxlength - dest_len;
4739 memcpy(&dest[dest_len], src, src_len);
4740 dest[dest_len + src_len] = 0;
4744 /*******************************************************************
4745 align a pointer to a multiple of 2 bytes
4746 ********************************************************************/
4747 char *align2(char *q, char *base)
4756 void print_asc(int level, unsigned char *buf,int len)
4760 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4763 void dump_data(int level,char *buf1,int len)
4765 unsigned char *buf = (unsigned char *)buf1;
4769 DEBUG(level,("[%03X] ",i));
4771 DEBUG(level,("%02X ",(int)buf[i]));
4773 if (i%8 == 0) DEBUG(level,(" "));
4775 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4776 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4777 if (i<len) DEBUG(level,("[%03X] ",i));
4785 if (n>8) DEBUG(level,(" "));
4786 while (n--) DEBUG(level,(" "));
4789 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4791 if (n>0) print_asc(level,&buf[i-n],n);
4792 DEBUG(level,("\n"));
4796 char *tab_depth(int depth)
4798 static pstring spaces;
4799 memset(spaces, ' ', depth * 4);
4800 spaces[depth * 4] = 0;
4804 /*****************************************************************
4805 Convert a SID to an ascii string.
4806 *****************************************************************/
4808 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
4812 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4813 uint32 ia = (sid->id_auth[5]) +
4814 (sid->id_auth[4] << 8 ) +
4815 (sid->id_auth[3] << 16) +
4816 (sid->id_auth[2] << 24);
4818 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4820 for (i = 0; i < sid->num_auths; i++)
4822 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4823 pstrcat(sidstr_out, subauth);
4826 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
4830 /*****************************************************************
4831 Convert a string to a SID. Returns True on success, False on fail.
4832 *****************************************************************/
4834 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
4838 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4841 memset((char *)sidout, '\0', sizeof(DOM_SID));
4843 if(StrnCaseCmp( sidstr, "S-", 2)) {
4844 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
4849 if(!next_token(&p, tok, "-", sizeof(tok))) {
4850 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4854 /* Get the revision number. */
4855 sidout->sid_rev_num = atoi(tok);
4857 if(!next_token(&p, tok, "-", sizeof(tok))) {
4858 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
4862 /* identauth in decimal should be < 2^32 */
4865 /* NOTE - the ia value is in big-endian format. */
4866 sidout->id_auth[0] = 0;
4867 sidout->id_auth[1] = 0;
4868 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
4869 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
4870 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
4871 sidout->id_auth[5] = (ia & 0x000000ff);
4873 sidout->num_auths = 0;
4875 while(next_token(&p, tok, "-", sizeof(tok)) &&
4876 sidout->num_auths < MAXSUBAUTHS) {
4878 * NOTE - the subauths are in native machine-endian format. They
4879 * are converted to little-endian when linearized onto the wire.
4881 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
4884 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
4889 /*****************************************************************************
4890 * Provide a checksum on a string
4892 * Input: s - the nul-terminated character string for which the checksum
4893 * will be calculated.
4895 * Output: The checksum value calculated for s.
4897 * ****************************************************************************
4899 int str_checksum(const char *s)
4907 res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
4912 } /* str_checksum */
4916 /*****************************************************************
4917 zero a memory area then free it. Used to catch bugs faster
4918 *****************************************************************/
4919 void zero_free(void *p, size_t size)
4926 /*****************************************************************
4927 set our open file limit to a requested max and return the limit
4928 *****************************************************************/
4929 int set_maxfiles(int requested_max)
4931 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4933 getrlimit(RLIMIT_NOFILE, &rlp);
4934 /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
4935 * account for the extra fd we need
4936 * as well as the log files and standard
4938 rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
4939 setrlimit(RLIMIT_NOFILE, &rlp);
4940 getrlimit(RLIMIT_NOFILE, &rlp);
4941 return rlp.rlim_cur;
4944 * No way to know - just guess...
4946 return requested_max;