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(NETGROUP) && defined (AUTOMOUNT))
26 #include <rpcsvc/nis.h>
28 #include "rpcsvc/ypclnt.h"
38 int Protocol = PROTOCOL_COREPLUS;
40 /* a default finfo structure to ensure all fields are sensible */
41 file_info def_finfo = {-1,0,0,0,0,0,0,""};
43 /* these are some file handles where debug info will be stored */
46 /* the client file descriptor */
49 /* the last IP received from */
50 struct in_addr lastip;
52 /* the last port received from */
55 /* this is used by the chaining code */
61 case handling on filenames
63 int case_default = CASE_LOWER;
68 /* the following control case operations - they are put here so the
69 client can link easily */
72 BOOL use_mangled_map = False;
73 BOOL short_case_preserve;
76 fstring remote_machine="";
77 fstring local_machine="";
78 fstring remote_arch="UNKNOWN";
79 static enum remote_arch_types ra_type = RA_UNKNOWN;
80 fstring remote_proto="UNKNOWN";
81 pstring myhostname="";
82 pstring user_socket_options="";
84 pstring sesssetup_user="";
85 pstring samlogon_user="";
87 BOOL sam_logon_in_ssb = False;
89 pstring global_myname = "";
90 fstring global_myworkgroup = "";
91 char **my_netbios_names;
93 int smb_read_error = 0;
95 static BOOL stdout_logging = False;
97 static char *filename_dos(char *path,char *buf);
100 /******************************************************************************
101 catch a sigusr2 - decrease the debug log level.
102 *****************************************************************************/
105 BlockSignals( True, SIGUSR2);
112 DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) );
114 BlockSignals( False, SIGUSR2);
115 #ifndef DONT_REINSTALL_SIG
116 signal(SIGUSR2, SIGNAL_CAST sig_usr2);
123 /**************************************************************************** **
124 catch a sigusr1 - increase the debug log level.
125 **************************************************************************** */
128 BlockSignals( True, SIGUSR1);
135 DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) );
137 BlockSignals( False, SIGUSR1);
138 #ifndef DONT_REINSTALL_SIG
139 signal(SIGUSR1, SIGNAL_CAST sig_usr1);
146 /*******************************************************************
147 get ready for syslog stuff
148 ******************************************************************/
149 void setup_logging(char *pname,BOOL interactive)
153 char *p = strrchr(pname,'/');
156 openlog(pname, LOG_PID, SYSLOG_FACILITY);
157 #else /* for old systems that have no facility codes. */
158 openlog(pname, LOG_PID);
163 stdout_logging = True;
169 BOOL append_log=False;
172 /****************************************************************************
174 ****************************************************************************/
175 void reopen_logs(void)
181 pstrcpy(fname,debugf);
182 if (lp_loaded() && (*lp_logfile()))
183 pstrcpy(fname,lp_logfile());
185 if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
187 int oldumask = umask(022);
188 pstrcpy(debugf,fname);
189 if (dbf) fclose(dbf);
191 dbf = fopen(debugf,"a");
193 dbf = fopen(debugf,"w");
194 if (dbf) setbuf(dbf,NULL);
209 /*******************************************************************
210 check if the log has grown too big
211 ********************************************************************/
212 static void check_log_size(void)
214 static int debug_count=0;
218 if (debug_count++ < 100 || getuid() != 0) return;
220 maxlog = lp_max_log_size() * 1024;
221 if (!dbf || maxlog <= 0) return;
223 if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
224 fclose(dbf); dbf = NULL;
226 if (dbf && file_size(debugf) > maxlog) {
228 fclose(dbf); dbf = NULL;
229 slprintf(name,sizeof(name)-1,"%s.old",debugf);
230 sys_rename(debugf,name);
238 /*******************************************************************
239 write an debug message on the debugfile. This is called by the DEBUG
241 ********************************************************************/
243 int Debug1(char *format_str, ...)
252 int old_errno = errno;
254 if (stdout_logging) {
256 va_start(ap, format_str);
259 format_str = va_arg(ap,char *);
261 vfprintf(dbf,format_str,ap);
268 if (!lp_syslog_only())
272 int oldumask = umask(022);
274 dbf = fopen(debugf,"a");
276 dbf = fopen(debugf,"w");
288 if (syslog_level < lp_syslog())
291 * map debug levels to syslog() priorities
292 * note that not all DEBUG(0, ...) calls are
295 static int priority_map[] = {
304 if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
306 priority = LOG_DEBUG;
308 priority = priority_map[syslog_level];
311 va_start(ap, format_str);
314 format_str = va_arg(ap,char *);
316 vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap);
320 syslog(priority, "%s", msgbuf);
325 if (!lp_syslog_only())
329 va_start(ap, format_str);
332 format_str = va_arg(ap,char *);
334 vfprintf(dbf,format_str,ap);
346 /****************************************************************************
347 find a suitable temporary directory. The result should be copied immediately
348 as it may be overwritten by a subsequent call
349 ****************************************************************************/
353 if ((p = getenv("TMPDIR"))) {
361 /****************************************************************************
362 determine if a file descriptor is in fact a socket
363 ****************************************************************************/
364 BOOL is_a_socket(int fd)
368 return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
372 static char *last_ptr=NULL;
374 /****************************************************************************
375 Get the next token from a string, return False if none found
376 handles double-quotes.
377 Based on a routine by GJC@VILLAGE.COM.
378 Extensively modified by Andrew.Tridgell@anu.edu.au
379 ****************************************************************************/
380 BOOL next_token(char **ptr,char *buff,char *sep)
385 if (!ptr) ptr = &last_ptr;
386 if (!ptr) return(False);
390 /* default to simple separators */
391 if (!sep) sep = " \t\n\r";
393 /* find the first non sep char */
394 while(*s && strchr(sep,*s)) s++;
397 if (! *s) return(False);
399 /* copy over the token */
400 for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
408 *ptr = (*s) ? s+1 : s;
415 /****************************************************************************
416 Convert list of tokens to array; dependent on above routine.
417 Uses last_ptr from above - bit of a hack.
418 ****************************************************************************/
419 char **toktocliplist(int *ctok, char *sep)
425 if (!sep) sep = " \t\n\r";
427 while(*s && strchr(sep,*s)) s++;
430 if (!*s) return(NULL);
434 while(*s && (!strchr(sep,*s))) s++;
435 while(*s && strchr(sep,*s)) *s++=0;
441 if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
453 /*******************************************************************
454 safely copies memory, ensuring no overlap problems.
455 this is only used if the machine does not have it's own memmove().
456 this is not the fastest algorithm in town, but it will do for our
458 ********************************************************************/
459 void *MemMove(void *dest,void *src,int size)
463 if (dest==src || !size) return(dest);
465 d = (unsigned long)dest;
466 s = (unsigned long)src;
468 if ((d >= (s+size)) || (s >= (d+size))) {
470 memcpy(dest,src,size);
476 /* we can forward copy */
477 if (s-d >= sizeof(int) &&
478 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
479 /* do it all as words */
480 int *idest = (int *)dest;
481 int *isrc = (int *)src;
483 for (i=0;i<size;i++) idest[i] = isrc[i];
486 char *cdest = (char *)dest;
487 char *csrc = (char *)src;
488 for (i=0;i<size;i++) cdest[i] = csrc[i];
493 /* must backward copy */
494 if (d-s >= sizeof(int) &&
495 !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
496 /* do it all as words */
497 int *idest = (int *)dest;
498 int *isrc = (int *)src;
500 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
503 char *cdest = (char *)dest;
504 char *csrc = (char *)src;
505 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
513 /****************************************************************************
514 prompte a dptr (to make it recently used)
515 ****************************************************************************/
516 void array_promote(char *array,int elsize,int element)
522 p = (char *)malloc(elsize);
526 DEBUG(5,("Ahh! Can't malloc\n"));
529 memcpy(p,array + element * elsize, elsize);
530 memmove(array + elsize,array,elsize*element);
531 memcpy(array,p,elsize);
535 enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
544 } socket_options[] = {
545 {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
546 {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
547 {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
549 {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
551 #ifdef IPTOS_LOWDELAY
552 {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
554 #ifdef IPTOS_THROUGHPUT
555 {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
558 {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
561 {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
564 {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
567 {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
570 {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
573 {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
579 /****************************************************************************
580 set user socket options
581 ****************************************************************************/
582 void set_socket_options(int fd, char *options)
586 while (next_token(&options,tok," \t,"))
591 BOOL got_value = False;
593 if ((p = strchr(tok,'=')))
600 for (i=0;socket_options[i].name;i++)
601 if (strequal(socket_options[i].name,tok))
604 if (!socket_options[i].name)
606 DEBUG(0,("Unknown socket option %s\n",tok));
610 switch (socket_options[i].opttype)
614 ret = setsockopt(fd,socket_options[i].level,
615 socket_options[i].option,(char *)&value,sizeof(int));
620 DEBUG(0,("syntax error - %s does not take a value\n",tok));
623 int on = socket_options[i].value;
624 ret = setsockopt(fd,socket_options[i].level,
625 socket_options[i].option,(char *)&on,sizeof(int));
631 DEBUG(0,("Failed to set socket option %s\n",tok));
637 /****************************************************************************
638 close the socket communication
639 ****************************************************************************/
640 void close_sockets(void )
646 /****************************************************************************
647 determine whether we are in the specified group
648 ****************************************************************************/
649 BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
653 if (group == current_gid) return(True);
655 for (i=0;i<ngroups;i++)
656 if (group == groups[i])
662 /****************************************************************************
663 this is a safer strcpy(), meant to prevent core dumps when nasty things happen
664 ****************************************************************************/
665 char *StrCpy(char *dest,char *src)
670 /* I don't want to get lazy with these ... */
672 DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
677 if (!dest) return(NULL);
682 while ((*d++ = *src++)) ;
686 /****************************************************************************
687 line strncpy but always null terminates. Make sure there is room!
688 ****************************************************************************/
689 char *StrnCpy(char *dest,char *src,int n)
692 if (!dest) return(NULL);
697 while (n-- && (*d++ = *src++)) ;
703 /*******************************************************************
704 copy an IP address from one buffer to another
705 ********************************************************************/
706 void putip(void *dest,void *src)
712 /****************************************************************************
713 interpret the weird netbios "name". Return the name type
714 ****************************************************************************/
715 static int name_interpret(char *in,char *out)
718 int len = (*in++) / 2;
722 if (len > 30 || len<1) return(0);
726 if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
730 *out = ((in[0]-'A')<<4) + (in[1]-'A');
738 /* Handle any scope names */
741 *out++ = '.'; /* Scope names are separated by periods */
742 len = *(unsigned char *)in++;
743 StrnCpy(out, in, len);
752 /****************************************************************************
753 mangle a name into netbios format
755 Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
756 ****************************************************************************/
757 int name_mangle( char *In, char *Out, char name_type )
765 /* Safely copy the input string, In, into buf[]. */
766 (void)memset( buf, 0, 20 );
770 (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
772 /* Place the length of the first field into the output buffer. */
776 /* Now convert the name to the rfc1001/1002 format. */
777 for( i = 0; i < 16; i++ )
779 c = toupper( buf[i] );
780 p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
781 p[(i*2)+1] = (c & 0x000F) + 'A';
786 /* Add the scope string. */
787 for( i = 0, len = 0; NULL != scope; i++, len++ )
795 return( name_len(Out) );
807 return( name_len(Out) );
810 /*******************************************************************
811 check if a file exists
812 ********************************************************************/
813 BOOL file_exist(char *fname,struct stat *sbuf)
816 if (!sbuf) sbuf = &st;
818 if (sys_stat(fname,sbuf) != 0)
821 return(S_ISREG(sbuf->st_mode));
824 /*******************************************************************
825 check a files mod time
826 ********************************************************************/
827 time_t file_modtime(char *fname)
831 if (sys_stat(fname,&st) != 0)
837 /*******************************************************************
838 check if a directory exists
839 ********************************************************************/
840 BOOL directory_exist(char *dname,struct stat *st)
847 if (sys_stat(dname,st) != 0)
850 ret = S_ISDIR(st->st_mode);
856 /*******************************************************************
857 returns the size in bytes of the named file
858 ********************************************************************/
859 uint32 file_size(char *file_name)
863 sys_stat(file_name,&buf);
867 /*******************************************************************
868 return a string representing an attribute for a file
869 ********************************************************************/
870 char *attrib_string(int mode)
872 static fstring attrstr;
876 if (mode & aVOLID) fstrcat(attrstr,"V");
877 if (mode & aDIR) fstrcat(attrstr,"D");
878 if (mode & aARCH) fstrcat(attrstr,"A");
879 if (mode & aHIDDEN) fstrcat(attrstr,"H");
880 if (mode & aSYSTEM) fstrcat(attrstr,"S");
881 if (mode & aRONLY) fstrcat(attrstr,"R");
887 /*******************************************************************
888 case insensitive string compararison
889 ********************************************************************/
890 int StrCaseCmp(char *s, char *t)
892 /* compare until we run out of string, either t or s, or find a difference */
893 /* We *must* use toupper rather than tolower here due to the
894 asynchronous upper to lower mapping.
896 #if !defined(KANJI_WIN95_COMPATIBILITY)
898 * For completeness we should put in equivalent code for code pages
899 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
900 * doubt anyone wants Samba to behave differently from Win95 and WinNT
901 * here. They both treat full width ascii characters as case senstive
902 * filenames (ie. they don't do the work we do here).
906 if(lp_client_code_page() == KANJI_CODEPAGE)
908 /* Win95 treats full width ascii characters as case sensitive. */
913 return toupper (*s) - toupper (*t);
914 else if (is_sj_alph (*s) && is_sj_alph (*t))
916 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
922 else if (is_shift_jis (*s) && is_shift_jis (*t))
924 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
927 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
933 else if (is_shift_jis (*s))
935 else if (is_shift_jis (*t))
939 diff = toupper (*s) - toupper (*t);
948 #endif /* KANJI_WIN95_COMPATIBILITY */
950 while (*s && *t && toupper(*s) == toupper(*t))
956 return(toupper(*s) - toupper(*t));
960 /*******************************************************************
961 case insensitive string compararison, length limited
962 ********************************************************************/
963 int StrnCaseCmp(char *s, char *t, int n)
965 /* compare until we run out of string, either t or s, or chars */
966 /* We *must* use toupper rather than tolower here due to the
967 asynchronous upper to lower mapping.
969 #if !defined(KANJI_WIN95_COMPATIBILITY)
971 * For completeness we should put in equivalent code for code pages
972 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
973 * doubt anyone wants Samba to behave differently from Win95 and WinNT
974 * here. They both treat full width ascii characters as case senstive
975 * filenames (ie. they don't do the work we do here).
979 if(lp_client_code_page() == KANJI_CODEPAGE)
981 /* Win95 treats full width ascii characters as case sensitive. */
986 return toupper (*s) - toupper (*t);
987 else if (is_sj_alph (*s) && is_sj_alph (*t))
989 diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
996 else if (is_shift_jis (*s) && is_shift_jis (*t))
998 diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
1001 diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
1008 else if (is_shift_jis (*s))
1010 else if (is_shift_jis (*t))
1014 diff = toupper (*s) - toupper (*t);
1025 #endif /* KANJI_WIN95_COMPATIBILITY */
1027 while (n && *s && *t && toupper(*s) == toupper(*t))
1034 /* not run out of chars - strings are different lengths */
1036 return(toupper(*s) - toupper(*t));
1038 /* identical up to where we run out of chars,
1039 and strings are same length */
1044 /*******************************************************************
1046 ********************************************************************/
1047 BOOL strequal(char *s1, char *s2)
1049 if (s1 == s2) return(True);
1050 if (!s1 || !s2) return(False);
1052 return(StrCaseCmp(s1,s2)==0);
1055 /*******************************************************************
1056 compare 2 strings up to and including the nth char.
1057 ******************************************************************/
1058 BOOL strnequal(char *s1,char *s2,int n)
1060 if (s1 == s2) return(True);
1061 if (!s1 || !s2 || !n) return(False);
1063 return(StrnCaseCmp(s1,s2,n)==0);
1066 /*******************************************************************
1067 compare 2 strings (case sensitive)
1068 ********************************************************************/
1069 BOOL strcsequal(char *s1,char *s2)
1071 if (s1 == s2) return(True);
1072 if (!s1 || !s2) return(False);
1074 return(strcmp(s1,s2)==0);
1078 /*******************************************************************
1079 convert a string to lower case
1080 ********************************************************************/
1081 void strlower(char *s)
1085 #if !defined(KANJI_WIN95_COMPATIBILITY)
1087 * For completeness we should put in equivalent code for code pages
1088 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1089 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1090 * here. They both treat full width ascii characters as case senstive
1091 * filenames (ie. they don't do the work we do here).
1095 if(lp_client_code_page() == KANJI_CODEPAGE)
1097 /* Win95 treats full width ascii characters as case sensitive. */
1098 if (is_shift_jis (*s))
1100 if (is_sj_upper (s[0], s[1]))
1101 s[1] = sj_tolower2 (s[1]);
1104 else if (is_kana (*s))
1116 #endif /* KANJI_WIN95_COMPATIBILITY */
1118 int skip = skip_multibyte_char( *s );
1131 /*******************************************************************
1132 convert a string to upper case
1133 ********************************************************************/
1134 void strupper(char *s)
1138 #if !defined(KANJI_WIN95_COMPATIBILITY)
1140 * For completeness we should put in equivalent code for code pages
1141 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1142 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1143 * here. They both treat full width ascii characters as case senstive
1144 * filenames (ie. they don't do the work we do here).
1148 if(lp_client_code_page() == KANJI_CODEPAGE)
1150 /* Win95 treats full width ascii characters as case sensitive. */
1151 if (is_shift_jis (*s))
1153 if (is_sj_lower (s[0], s[1]))
1154 s[1] = sj_toupper2 (s[1]);
1157 else if (is_kana (*s))
1169 #endif /* KANJI_WIN95_COMPATIBILITY */
1171 int skip = skip_multibyte_char( *s );
1184 /*******************************************************************
1185 convert a string to "normal" form
1186 ********************************************************************/
1187 void strnorm(char *s)
1189 if (case_default == CASE_UPPER)
1195 /*******************************************************************
1196 check if a string is in "normal" case
1197 ********************************************************************/
1198 BOOL strisnormal(char *s)
1200 if (case_default == CASE_UPPER)
1201 return(!strhaslower(s));
1203 return(!strhasupper(s));
1207 /****************************************************************************
1209 ****************************************************************************/
1210 void string_replace(char *s,char oldc,char newc)
1215 skip = skip_multibyte_char( *s );
1227 /****************************************************************************
1228 make a file into unix format
1229 ****************************************************************************/
1230 void unix_format(char *fname)
1233 string_replace(fname,'\\','/');
1237 pstrcpy(namecopy,fname);
1239 pstrcat(fname,namecopy);
1243 /****************************************************************************
1244 make a file into dos format
1245 ****************************************************************************/
1246 void dos_format(char *fname)
1248 string_replace(fname,'/','\\');
1251 /*******************************************************************
1252 show a smb message structure
1253 ********************************************************************/
1254 void show_msg(char *buf)
1259 if (DEBUGLEVEL < 5) return;
1261 DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
1263 (int)CVAL(buf,smb_com),
1264 (int)CVAL(buf,smb_rcls),
1265 (int)CVAL(buf,smb_reh),
1266 (int)SVAL(buf,smb_err),
1267 (int)CVAL(buf,smb_flg),
1268 (int)SVAL(buf,smb_flg2)));
1269 DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
1270 (int)SVAL(buf,smb_tid),
1271 (int)SVAL(buf,smb_pid),
1272 (int)SVAL(buf,smb_uid),
1273 (int)SVAL(buf,smb_mid),
1274 (int)CVAL(buf,smb_wct)));
1276 for (i=0;i<(int)CVAL(buf,smb_wct);i++)
1278 DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
1279 SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
1282 bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
1284 DEBUG(5,("smb_bcc=%d\n",bcc));
1286 if (DEBUGLEVEL < 10) return;
1288 if (DEBUGLEVEL < 50)
1290 bcc = MIN(bcc, 512);
1293 dump_data(10, smb_buf(buf), bcc);
1295 /*******************************************************************
1296 return the length of an smb packet
1297 ********************************************************************/
1298 int smb_len(char *buf)
1300 return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
1303 /*******************************************************************
1304 set the length of an smb packet
1305 ********************************************************************/
1306 void _smb_setlen(char *buf,int len)
1309 buf[1] = (len&0x10000)>>16;
1310 buf[2] = (len&0xFF00)>>8;
1314 /*******************************************************************
1315 set the length and marker of an smb packet
1316 ********************************************************************/
1317 void smb_setlen(char *buf,int len)
1319 _smb_setlen(buf,len);
1327 /*******************************************************************
1328 setup the word count and byte count for a smb message
1329 ********************************************************************/
1330 int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
1333 bzero(buf + smb_size,num_words*2 + num_bytes);
1334 CVAL(buf,smb_wct) = num_words;
1335 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
1336 smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
1337 return (smb_size + num_words*2 + num_bytes);
1340 /*******************************************************************
1341 return the number of smb words
1342 ********************************************************************/
1343 int smb_numwords(char *buf)
1345 return (CVAL(buf,smb_wct));
1348 /*******************************************************************
1349 return the size of the smb_buf region of a message
1350 ********************************************************************/
1351 int smb_buflen(char *buf)
1353 return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
1356 /*******************************************************************
1357 return a pointer to the smb_buf data area
1358 ********************************************************************/
1359 int smb_buf_ofs(char *buf)
1361 return (smb_size + CVAL(buf,smb_wct)*2);
1364 /*******************************************************************
1365 return a pointer to the smb_buf data area
1366 ********************************************************************/
1367 char *smb_buf(char *buf)
1369 return (buf + smb_buf_ofs(buf));
1372 /*******************************************************************
1373 return the SMB offset into an SMB buffer
1374 ********************************************************************/
1375 int smb_offset(char *p,char *buf)
1377 return(PTR_DIFF(p,buf+4) + chain_size);
1381 /*******************************************************************
1382 skip past some strings in a buffer
1383 ********************************************************************/
1384 char *skip_string(char *buf,int n)
1387 buf += strlen(buf) + 1;
1391 /*******************************************************************
1392 trim the specified elements off the front and back of a string
1393 ********************************************************************/
1394 BOOL trim_string(char *s,char *front,char *back)
1397 while (front && *front && strncmp(s,front,strlen(front)) == 0)
1403 if (!(*p = p[strlen(front)]))
1408 while (back && *back && strlen(s) >= strlen(back) &&
1409 (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
1412 s[strlen(s)-strlen(back)] = 0;
1418 /*******************************************************************
1419 reduce a file name, removing .. elements.
1420 ********************************************************************/
1421 void dos_clean_name(char *s)
1425 DEBUG(3,("dos_clean_name [%s]\n",s));
1427 /* remove any double slashes */
1428 string_sub(s, "\\\\", "\\");
1430 while ((p = strstr(s,"\\..\\")) != NULL)
1437 if ((p=strrchr(s,'\\')) != NULL)
1444 trim_string(s,NULL,"\\..");
1446 string_sub(s, "\\.\\", "\\");
1449 /*******************************************************************
1450 reduce a file name, removing .. elements.
1451 ********************************************************************/
1452 void unix_clean_name(char *s)
1456 DEBUG(3,("unix_clean_name [%s]\n",s));
1458 /* remove any double slashes */
1459 string_sub(s, "//","/");
1461 /* Remove leading ./ characters */
1462 if(strncmp(s, "./", 2) == 0) {
1463 trim_string(s, "./", NULL);
1468 while ((p = strstr(s,"/../")) != NULL)
1475 if ((p=strrchr(s,'/')) != NULL)
1482 trim_string(s,NULL,"/..");
1486 /*******************************************************************
1487 a wrapper for the normal chdir() function
1488 ********************************************************************/
1489 int ChDir(char *path)
1492 static pstring LastDir="";
1494 if (strcsequal(path,".")) return(0);
1496 if (*path == '/' && strcsequal(LastDir,path)) return(0);
1497 DEBUG(3,("chdir to %s\n",path));
1498 res = sys_chdir(path);
1500 pstrcpy(LastDir,path);
1504 /* number of list structures for a caching GetWd function. */
1505 #define MAX_GETWDCACHE (50)
1513 } ino_list[MAX_GETWDCACHE];
1515 BOOL use_getwd_cache=True;
1517 /*******************************************************************
1518 return the absolute current directory path
1519 ********************************************************************/
1520 char *GetWd(char *str)
1523 static BOOL getwd_cache_init = False;
1524 struct stat st, st2;
1529 if (!use_getwd_cache)
1530 return(sys_getwd(str));
1532 /* init the cache */
1533 if (!getwd_cache_init)
1535 getwd_cache_init = True;
1536 for (i=0;i<MAX_GETWDCACHE;i++)
1538 string_init(&ino_list[i].text,"");
1539 ino_list[i].valid = False;
1543 /* Get the inode of the current directory, if this doesn't work we're
1546 if (stat(".",&st) == -1)
1548 DEBUG(0,("Very strange, couldn't stat \".\"\n"));
1549 return(sys_getwd(str));
1553 for (i=0; i<MAX_GETWDCACHE; i++)
1554 if (ino_list[i].valid)
1557 /* If we have found an entry with a matching inode and dev number
1558 then find the inode number for the directory in the cached string.
1559 If this agrees with that returned by the stat for the current
1560 directory then all is o.k. (but make sure it is a directory all
1563 if (st.st_ino == ino_list[i].inode &&
1564 st.st_dev == ino_list[i].dev)
1566 if (stat(ino_list[i].text,&st2) == 0)
1568 if (st.st_ino == st2.st_ino &&
1569 st.st_dev == st2.st_dev &&
1570 (st2.st_mode & S_IFMT) == S_IFDIR)
1572 pstrcpy (str, ino_list[i].text);
1574 /* promote it for future use */
1575 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1580 /* If the inode is different then something's changed,
1581 scrub the entry and start from scratch. */
1582 ino_list[i].valid = False;
1589 /* We don't have the information to hand so rely on traditional methods.
1590 The very slow getcwd, which spawns a process on some systems, or the
1591 not quite so bad getwd. */
1595 DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
1601 DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
1603 /* add it to the cache */
1604 i = MAX_GETWDCACHE - 1;
1605 string_set(&ino_list[i].text,s);
1606 ino_list[i].dev = st.st_dev;
1607 ino_list[i].inode = st.st_ino;
1608 ino_list[i].valid = True;
1610 /* put it at the top of the list */
1611 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
1618 /*******************************************************************
1619 reduce a file name, removing .. elements and checking that
1620 it is below dir in the heirachy. This uses GetWd() and so must be run
1621 on the system that has the referenced file system.
1623 widelinks are allowed if widelinks is true
1624 ********************************************************************/
1625 BOOL reduce_name(char *s,char *dir,BOOL widelinks)
1627 #ifndef REDUCE_PATHS
1635 BOOL relative = (*s != '/');
1637 *dir2 = *wd = *base_name = *newname = 0;
1642 /* can't have a leading .. */
1643 if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
1645 DEBUG(3,("Illegal file name? (%s)\n",s));
1655 DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
1657 /* remove any double slashes */
1658 string_sub(s,"//","/");
1660 pstrcpy(base_name,s);
1661 p = strrchr(base_name,'/');
1668 DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
1672 if (ChDir(dir) != 0)
1674 DEBUG(0,("couldn't chdir to %s\n",dir));
1680 DEBUG(0,("couldn't getwd for %s\n",dir));
1686 if (p && (p != base_name))
1689 if (strcmp(p+1,".")==0)
1691 if (strcmp(p+1,"..")==0)
1695 if (ChDir(base_name) != 0)
1698 DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
1702 if (!GetWd(newname))
1705 DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
1709 if (p && (p != base_name))
1711 pstrcat(newname,"/");
1712 pstrcat(newname,p+1);
1716 int l = strlen(dir2);
1717 if (dir2[l-1] == '/')
1720 if (strncmp(newname,dir2,l) != 0)
1723 DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
1729 if (newname[l] == '/')
1730 pstrcpy(s,newname + l + 1);
1732 pstrcpy(s,newname+l);
1743 DEBUG(3,("reduced to %s\n",s));
1748 /****************************************************************************
1750 ****************************************************************************/
1751 static void expand_one(char *Mask,int len)
1754 while ((p1 = strchr(Mask,'*')) != NULL)
1756 int lfill = (len+1) - strlen(Mask);
1757 int l1= (p1 - Mask);
1760 memset(tmp+l1,'?',lfill);
1761 pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
1766 /****************************************************************************
1767 expand a wildcard expression, replacing *s with ?s
1768 ****************************************************************************/
1769 void expand_mask(char *Mask,BOOL doext)
1774 BOOL hasdot = False;
1776 BOOL absolute = (*Mask == '\\');
1778 *mbeg = *mext = *dirpart = *filepart = 0;
1780 /* parse the directory and filename */
1781 if (strchr(Mask,'\\'))
1782 dirname_dos(Mask,dirpart);
1784 filename_dos(Mask,filepart);
1786 pstrcpy(mbeg,filepart);
1787 if ((p1 = strchr(mbeg,'.')) != NULL)
1797 if (strlen(mbeg) > 8)
1799 pstrcpy(mext,mbeg + 8);
1805 pstrcpy(mbeg,"????????");
1806 if ((*mext == 0) && doext && !hasdot)
1807 pstrcpy(mext,"???");
1809 if (strequal(mbeg,"*") && *mext==0)
1817 pstrcpy(Mask,dirpart);
1818 if (*dirpart || absolute) pstrcat(Mask,"\\");
1823 DEBUG(6,("Mask expanded to [%s]\n",Mask));
1827 /****************************************************************************
1828 does a string have any uppercase chars in it?
1829 ****************************************************************************/
1830 BOOL strhasupper(char *s)
1834 #if !defined(KANJI_WIN95_COMPATIBILITY)
1836 * For completeness we should put in equivalent code for code pages
1837 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1838 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1839 * here. They both treat full width ascii characters as case senstive
1840 * filenames (ie. they don't do the work we do here).
1844 if(lp_client_code_page() == KANJI_CODEPAGE)
1846 /* Win95 treats full width ascii characters as case sensitive. */
1847 if (is_shift_jis (*s))
1849 else if (is_kana (*s))
1859 #endif /* KANJI_WIN95_COMPATIBILITY */
1869 /****************************************************************************
1870 does a string have any lowercase chars in it?
1871 ****************************************************************************/
1872 BOOL strhaslower(char *s)
1876 #if !defined(KANJI_WIN95_COMPATIBILITY)
1878 * For completeness we should put in equivalent code for code pages
1879 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1880 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1881 * here. They both treat full width ascii characters as case senstive
1882 * filenames (ie. they don't do the work we do here).
1886 if(lp_client_code_page() == KANJI_CODEPAGE)
1888 /* Win95 treats full width ascii characters as case sensitive. */
1889 if (is_shift_jis (*s))
1891 if (is_sj_upper (s[0], s[1]))
1893 if (is_sj_lower (s[0], s[1]))
1897 else if (is_kana (*s))
1909 #endif /* KANJI_WIN95_COMPATIBILITY */
1919 /****************************************************************************
1920 find the number of chars in a string
1921 ****************************************************************************/
1922 int count_chars(char *s,char c)
1926 #if !defined(KANJI_WIN95_COMPATIBILITY)
1928 * For completeness we should put in equivalent code for code pages
1929 * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
1930 * doubt anyone wants Samba to behave differently from Win95 and WinNT
1931 * here. They both treat full width ascii characters as case senstive
1932 * filenames (ie. they don't do the work we do here).
1936 if(lp_client_code_page() == KANJI_CODEPAGE)
1938 /* Win95 treats full width ascii characters as case sensitive. */
1941 if (is_shift_jis (*s))
1952 #endif /* KANJI_WIN95_COMPATIBILITY */
1965 /****************************************************************************
1967 ****************************************************************************/
1968 void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
1973 pstrcpy(mask2,mask);
1975 if ((mode & aDIR) != 0)
1978 memset(buf+1,' ',11);
1979 if ((p = strchr(mask2,'.')) != NULL)
1982 memcpy(buf+1,mask2,MIN(strlen(mask2),8));
1983 memcpy(buf+9,p+1,MIN(strlen(p+1),3));
1987 memcpy(buf+1,mask2,MIN(strlen(mask2),11));
1989 bzero(buf+21,DIR_STRUCT_SIZE-21);
1990 CVAL(buf,21) = mode;
1991 put_dos_date(buf,22,date);
1992 SSVAL(buf,26,size & 0xFFFF);
1993 SSVAL(buf,28,size >> 16);
1994 StrnCpy(buf+30,fname,12);
1995 if (!case_sensitive)
1997 DEBUG(8,("put name [%s] into dir struct\n",buf+30));
2001 /*******************************************************************
2002 close the low 3 fd's and open dev/null in their place
2003 ********************************************************************/
2004 void close_low_fds(void)
2008 close(0); close(1); close(2);
2009 /* try and use up these file descriptors, so silly
2010 library routines writing to stdout etc won't cause havoc */
2012 fd = open("/dev/null",O_RDWR,0);
2013 if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
2015 DEBUG(0,("Can't open /dev/null\n"));
2019 DEBUG(0,("Didn't get file descriptor %d\n",i));
2025 /****************************************************************************
2026 Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
2028 if SYSV use O_NDELAY
2030 ****************************************************************************/
2031 int set_blocking(int fd, BOOL set)
2035 #define FLAG_TO_SET O_NONBLOCK
2038 #define FLAG_TO_SET O_NDELAY
2040 #define FLAG_TO_SET FNDELAY
2044 if((val = fcntl(fd, F_GETFL, 0)) == -1)
2046 if(set) /* Turn blocking on - ie. clear nonblock flag */
2047 val &= ~FLAG_TO_SET;
2050 return fcntl( fd, F_SETFL, val);
2055 /****************************************************************************
2057 ****************************************************************************/
2058 int write_socket(int fd,char *buf,int len)
2064 DEBUG(6,("write_socket(%d,%d)\n",fd,len));
2065 ret = write_data(fd,buf,len);
2067 DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
2069 DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
2070 len, fd, strerror(errno) ));
2075 /****************************************************************************
2077 ****************************************************************************/
2078 int read_udp_socket(int fd,char *buf,int len)
2081 struct sockaddr_in sock;
2084 socklen = sizeof(sock);
2085 bzero((char *)&sock,socklen);
2086 bzero((char *)&lastip,sizeof(lastip));
2087 ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
2089 DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
2093 lastip = sock.sin_addr;
2094 lastport = ntohs(sock.sin_port);
2096 DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n",
2097 inet_ntoa(lastip), lastport, ret));
2102 /****************************************************************************
2103 read data from a device with a timout in msec.
2104 mincount = if timeout, minimum to read before returning
2105 maxcount = number to be read.
2106 ****************************************************************************/
2107 int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
2113 struct timeval timeout;
2115 /* just checking .... */
2116 if (maxcnt <= 0) return(0);
2121 if (time_out <= 0) {
2122 if (mincnt == 0) mincnt = maxcnt;
2124 while (nread < mincnt) {
2125 readret = read(fd, buf + nread, maxcnt - nread);
2127 smb_read_error = READ_EOF;
2131 if (readret == -1) {
2132 smb_read_error = READ_ERROR;
2140 /* Most difficult - timeout read */
2141 /* If this is ever called on a disk file and
2142 mincnt is greater then the filesize then
2143 system performance will suffer severely as
2144 select always return true on disk files */
2146 /* Set initial timeout */
2147 timeout.tv_sec = time_out / 1000;
2148 timeout.tv_usec = 1000 * (time_out % 1000);
2150 for (nread=0; nread<mincnt; )
2155 selrtn = sys_select(&fds,&timeout);
2157 /* Check if error */
2159 /* something is wrong. Maybe the socket is dead? */
2160 smb_read_error = READ_ERROR;
2164 /* Did we timeout ? */
2166 smb_read_error = READ_TIMEOUT;
2170 readret = read(fd, buf+nread, maxcnt-nread);
2172 /* we got EOF on the file descriptor */
2173 smb_read_error = READ_EOF;
2177 if (readret == -1) {
2178 /* the descriptor is probably dead */
2179 smb_read_error = READ_ERROR;
2186 /* Return the number we got */
2190 /****************************************************************************
2191 read data from the client. Maxtime is in milliseconds
2192 ****************************************************************************/
2193 int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
2198 struct timeval timeout;
2203 timeout.tv_sec = maxtime / 1000;
2204 timeout.tv_usec = (maxtime % 1000) * 1000;
2206 selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
2208 if (!FD_ISSET(fd,&fds))
2211 nread = read_udp_socket(fd, buffer, bufsize);
2213 /* return the number got */
2217 /*******************************************************************
2218 find the difference in milliseconds between two struct timeval
2220 ********************************************************************/
2221 int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
2223 return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
2224 ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
2227 /****************************************************************************
2228 send a keepalive packet (rfc1002)
2229 ****************************************************************************/
2230 BOOL send_keepalive(int client)
2232 unsigned char buf[4];
2235 buf[1] = buf[2] = buf[3] = 0;
2237 return(write_data(client,(char *)buf,4) == 4);
2242 /****************************************************************************
2243 read data from the client, reading exactly N bytes.
2244 ****************************************************************************/
2245 int read_data(int fd,char *buffer,int N)
2254 ret = read(fd,buffer + total,N - total);
2256 smb_read_error = READ_EOF;
2260 smb_read_error = READ_ERROR;
2269 /****************************************************************************
2271 ****************************************************************************/
2272 int write_data(int fd,char *buffer,int N)
2279 ret = write(fd,buffer + total,N - total);
2281 if (ret == -1) return -1;
2282 if (ret == 0) return total;
2290 /****************************************************************************
2291 transfer some data between two fd's
2292 ****************************************************************************/
2293 int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
2295 static char *buf=NULL;
2300 DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
2303 size = lp_readsize();
2304 size = MAX(size,1024);
2307 while (!buf && size>0) {
2308 buf = (char *)Realloc(buf,size+8);
2309 if (!buf) size /= 2;
2313 DEBUG(0,("Can't allocate transfer buffer!\n"));
2317 abuf = buf + (align%8);
2324 int s = MIN(n,size);
2329 if (header && (headlen >= MIN(s,1024))) {
2339 if (header && headlen > 0)
2341 ret = MIN(headlen,size);
2342 memcpy(buf1,header,ret);
2345 if (headlen <= 0) header = NULL;
2349 ret += read(infd,buf1+ret,s-ret);
2353 ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
2354 if (ret2 > 0) total += ret2;
2355 /* if we can't write then dump excess data */
2357 transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
2359 if (ret <= 0 || ret2 != ret)
2367 /****************************************************************************
2368 read 4 bytes of a smb packet and return the smb length of the packet
2369 store the result in the buffer
2370 This version of the function will return a length of zero on receiving
2372 ****************************************************************************/
2373 static int read_smb_length_return_keepalive(int fd,char *inbuf,int timeout)
2375 int len=0, msg_type;
2381 ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
2383 ok = (read_data(fd,inbuf,4) == 4);
2388 len = smb_len(inbuf);
2389 msg_type = CVAL(inbuf,0);
2391 if (msg_type == 0x85)
2392 DEBUG(5,("Got keepalive packet\n"));
2395 DEBUG(10,("got smb length of %d\n",len));
2400 /****************************************************************************
2401 read 4 bytes of a smb packet and return the smb length of the packet
2402 store the result in the buffer. This version of the function will
2403 never return a session keepalive (length of zero).
2404 ****************************************************************************/
2405 int read_smb_length(int fd,char *inbuf,int timeout)
2411 len = read_smb_length_return_keepalive(fd, inbuf, timeout);
2416 /* Ignore session keepalives. */
2417 if(CVAL(inbuf,0) != 0x85)
2424 /****************************************************************************
2425 read an smb from a fd. Note that the buffer *MUST* be of size
2426 BUFFER_SIZE+SAFETY_MARGIN.
2427 The timeout is in milli seconds.
2429 This function will return on a
2430 receipt of a session keepalive packet.
2431 ****************************************************************************/
2432 BOOL receive_smb(int fd,char *buffer, int timeout)
2438 bzero(buffer,smb_size + 100);
2440 len = read_smb_length_return_keepalive(fd,buffer,timeout);
2444 if (len > BUFFER_SIZE) {
2445 DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
2446 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
2451 ret = read_data(fd,buffer+4,len);
2453 smb_read_error = READ_ERROR;
2460 /****************************************************************************
2461 read an smb from a fd ignoring all keepalive packets. Note that the buffer
2462 *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN.
2463 The timeout is in milli seconds
2465 This is exactly the same as receive_smb except that it never returns
2466 a session keepalive packet (just as receive_smb used to do).
2467 receive_smb was changed to return keepalives as the oplock processing means this call
2468 should never go into a blocking read.
2469 ****************************************************************************/
2471 BOOL client_receive_smb(int fd,char *buffer, int timeout)
2477 ret = receive_smb(fd, buffer, timeout);
2482 /* Ignore session keepalive packets. */
2483 if(CVAL(buffer,0) != 0x85)
2489 /****************************************************************************
2490 read a message from a udp fd.
2491 The timeout is in milli seconds
2492 ****************************************************************************/
2493 BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
2495 struct sockaddr_in from;
2496 int fromlen = sizeof(from);
2510 to.tv_sec = timeout / 1000;
2511 to.tv_usec = (timeout % 1000) * 1000;
2513 selrtn = sys_select(&fds,&to);
2515 /* Check if error */
2518 /* something is wrong. Maybe the socket is dead? */
2519 smb_read_error = READ_ERROR;
2523 /* Did we timeout ? */
2526 smb_read_error = READ_TIMEOUT;
2532 * Read a loopback udp message.
2534 msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
2535 buffer_len - UDP_CMD_HEADER_LEN, 0,
2536 (struct sockaddr *)&from, &fromlen);
2540 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
2544 /* Validate message length. */
2545 if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
2547 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
2549 buffer_len - UDP_CMD_HEADER_LEN));
2553 /* Validate message from address (must be localhost). */
2554 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
2556 DEBUG(0,("receive_local_message: invalid 'from' address \
2557 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
2561 /* Setup the message header */
2562 SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
2563 SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
2568 /****************************************************************************
2569 structure to hold a linked list of local messages.
2571 ****************************************************************************/
2573 typedef struct _message_list {
2574 struct _message_list *msg_next;
2577 } pending_message_list;
2579 static pending_message_list *smb_msg_head = NULL;
2581 /****************************************************************************
2582 Function to push a linked list of local messages ready
2584 ****************************************************************************/
2586 static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
2588 pending_message_list *msg = (pending_message_list *)
2589 malloc(sizeof(pending_message_list));
2593 DEBUG(0,("push_message: malloc fail (1)\n"));
2597 msg->msg_buf = (char *)malloc(msg_len);
2598 if(msg->msg_buf == NULL)
2600 DEBUG(0,("push_local_message: malloc fail (2)\n"));
2605 memcpy(msg->msg_buf, buf, msg_len);
2606 msg->msg_len = msg_len;
2608 msg->msg_next = *pml;
2614 /****************************************************************************
2615 Function to push a linked list of local smb messages ready
2617 ****************************************************************************/
2619 BOOL push_smb_message(char *buf, int msg_len)
2621 return push_local_message(&smb_msg_head, buf, msg_len);
2624 /****************************************************************************
2625 Do a select on an two fd's - with timeout.
2627 If a local udp message has been pushed onto the
2628 queue (this can only happen during oplock break
2629 processing) return this first.
2631 If a pending smb message has been pushed onto the
2632 queue (this can only happen during oplock break
2633 processing) return this next.
2635 If the first smbfd is ready then read an smb from it.
2636 if the second (loopback UDP) fd is ready then read a message
2637 from it and setup the buffer header to identify the length
2639 Returns False on timeout or error.
2642 The timeout is in milli seconds
2643 ****************************************************************************/
2644 BOOL receive_message_or_smb(int smbfd, int oplock_fd,
2645 char *buffer, int buffer_len,
2646 int timeout, BOOL *got_smb)
2657 * Check to see if we already have a message on the smb queue.
2658 * If so - copy and return it.
2663 pending_message_list *msg = smb_msg_head;
2664 memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
2665 smb_msg_head = msg->msg_next;
2667 /* Free the message we just copied. */
2668 free((char *)msg->msg_buf);
2672 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
2678 FD_SET(oplock_fd,&fds);
2680 to.tv_sec = timeout / 1000;
2681 to.tv_usec = (timeout % 1000) * 1000;
2683 selrtn = sys_select(&fds,timeout>0?&to:NULL);
2685 /* Check if error */
2687 /* something is wrong. Maybe the socket is dead? */
2688 smb_read_error = READ_ERROR;
2692 /* Did we timeout ? */
2694 smb_read_error = READ_TIMEOUT;
2698 if (FD_ISSET(smbfd,&fds))
2701 return receive_smb(smbfd, buffer, 0);
2705 return receive_local_message(oplock_fd, buffer, buffer_len, 0);
2709 /****************************************************************************
2711 ****************************************************************************/
2712 BOOL send_smb(int fd,char *buffer)
2716 len = smb_len(buffer) + 4;
2718 while (nwritten < len)
2720 ret = write_socket(fd,buffer+nwritten,len - nwritten);
2723 DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
2735 /****************************************************************************
2736 find a pointer to a netbios name
2737 ****************************************************************************/
2738 char *name_ptr(char *buf,int ofs)
2740 unsigned char c = *(unsigned char *)(buf+ofs);
2742 if ((c & 0xC0) == 0xC0)
2746 memcpy(p,buf+ofs,2);
2749 DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
2756 /****************************************************************************
2757 extract a netbios name from a buf
2758 ****************************************************************************/
2759 int name_extract(char *buf,int ofs,char *name)
2761 char *p = name_ptr(buf,ofs);
2762 int d = PTR_DIFF(p,buf+ofs);
2764 if (d < -50 || d > 50) return(0);
2765 return(name_interpret(p,name));
2768 /****************************************************************************
2769 return the total storage length of a mangled name
2770 ****************************************************************************/
2771 int name_len( char *s )
2775 /* If the two high bits of the byte are set, return 2. */
2776 if( 0xC0 == (*(unsigned char *)s & 0xC0) )
2779 /* Add up the length bytes. */
2780 for( len = 1; (*s); s += (*s) + 1 )
2788 /****************************************************************************
2789 send a single packet to a port on another machine
2790 ****************************************************************************/
2791 BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
2795 struct sockaddr_in sock_out;
2800 /* create a socket to write to */
2801 out_fd = socket(AF_INET, type, 0);
2804 DEBUG(0,("socket failed"));
2808 /* set the address and port */
2809 bzero((char *)&sock_out,sizeof(sock_out));
2810 putip((char *)&sock_out.sin_addr,(char *)&ip);
2811 sock_out.sin_port = htons( port );
2812 sock_out.sin_family = AF_INET;
2815 DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
2816 len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
2819 ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
2822 DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
2823 inet_ntoa(ip),port,strerror(errno)));
2829 /*******************************************************************
2830 sleep for a specified number of milliseconds
2831 ********************************************************************/
2835 struct timeval tval,t1,t2;
2842 tval.tv_sec = (t-tdiff)/1000;
2843 tval.tv_usec = 1000*((t-tdiff)%1000);
2847 sys_select(&fds,&tval);
2850 tdiff = TvalDiff(&t1,&t2);
2854 /****************************************************************************
2855 check if a string is part of a list
2856 ****************************************************************************/
2857 BOOL in_list(char *s,char *list,BOOL casesensitive)
2862 if (!list) return(False);
2864 while (next_token(&p,tok,LIST_SEP))
2866 if (casesensitive) {
2867 if (strcmp(tok,s) == 0)
2870 if (StrCaseCmp(tok,s) == 0)
2877 /* this is used to prevent lots of mallocs of size 1 */
2878 static char *null_string = NULL;
2880 /****************************************************************************
2881 set a string value, allocing the space for the string
2882 ****************************************************************************/
2883 BOOL string_init(char **dest,char *src)
2894 null_string = (char *)malloc(1);
2897 *dest = null_string;
2901 (*dest) = (char *)malloc(l+1);
2902 if ((*dest) == NULL) {
2903 DEBUG(0,("Out of memory in string_init\n"));
2912 /****************************************************************************
2914 ****************************************************************************/
2915 void string_free(char **s)
2917 if (!s || !(*s)) return;
2918 if (*s == null_string)
2924 /****************************************************************************
2925 set a string value, allocing the space for the string, and deallocating any
2927 ****************************************************************************/
2928 BOOL string_set(char **dest,char *src)
2932 return(string_init(dest,src));
2935 /****************************************************************************
2936 substitute a string for a pattern in another string. Make sure there is
2939 This routine looks for pattern in s and replaces it with
2940 insert. It may do multiple replacements.
2942 return True if a substitution was done.
2943 ****************************************************************************/
2944 BOOL string_sub(char *s,char *pattern,char *insert)
2950 if (!insert || !pattern || !s) return(False);
2953 lp = strlen(pattern);
2954 li = strlen(insert);
2956 if (!*pattern) return(False);
2958 while (lp <= ls && (p = strstr(s,pattern)))
2961 memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
2962 memcpy(p,insert,li);
2971 /*********************************************************
2972 * Recursive routine that is called by mask_match.
2973 * Does the actual matching.
2974 *********************************************************/
2975 BOOL do_match(char *str, char *regexp, int case_sig)
2979 for( p = regexp; *p && *str; ) {
2986 /* Look for a character matching
2987 the one after the '*' */
2990 return True; /* Automatic match */
2992 while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
2994 if(do_match(str,p,case_sig))
3008 if(toupper(*str) != toupper(*p))
3018 if (!*p && str[0] == '.' && str[1] == 0)
3021 if (!*str && *p == '?')
3023 while (*p == '?') p++;
3027 if(!*str && (*p == '*' && p[1] == '\0'))
3033 /*********************************************************
3034 * Routine to match a given string with a regexp - uses
3035 * simplified regexp that takes * and ? only. Case can be
3036 * significant or not.
3037 *********************************************************/
3038 BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
3042 fstring ebase,eext,sbase,sext;
3046 /* Make local copies of str and regexp */
3047 StrnCpy(p1,regexp,sizeof(pstring)-1);
3048 StrnCpy(p2,str,sizeof(pstring)-1);
3050 if (!strchr(p2,'.')) {
3055 if (!strchr(p1,'.')) {
3063 string_sub(p1,"*.*","*");
3064 string_sub(p1,".*","*");
3068 /* Remove any *? and ** as they are meaningless */
3069 for(p = p1; *p; p++)
3070 while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
3071 (void)pstrcpy( &p[1], &p[2]);
3073 if (strequal(p1,"*")) return(True);
3075 DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
3081 if ((p=strrchr(p1,'.'))) {
3090 if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
3102 * Match each component of the path, split up by '.'
3105 char *fp, *rp, *cp2, *cp1;
3107 for( cp1 = ebase, cp2 = sbase; cp1;) {
3108 fp = strchr(cp2, '.');
3111 rp = strchr(cp1, '.');
3114 if(!do_match(cp2, cp1, case_sig))
3116 cp2 = fp ? fp + 1 : "";
3117 cp1 = rp ? rp + 1 : NULL;
3122 matched = do_match(sbase,ebase,case_sig) && do_match(sext,eext,case_sig);
3125 DEBUG(8,("mask_match returning %d\n", matched));
3132 /****************************************************************************
3133 become a daemon, discarding the controlling terminal
3134 ****************************************************************************/
3135 void become_daemon(void)
3137 #ifndef NO_FORK_DEBUG
3141 /* detach from the terminal */
3144 #else /* USE_SETSID */
3147 int i = open("/dev/tty", O_RDWR);
3150 ioctl(i, (int) TIOCNOTTY, (char *)0);
3154 #endif /* TIOCNOTTY */
3155 #endif /* USE_SETSID */
3156 /* Close fd's 0,1,2. Needed if started by rsh */
3158 #endif /* NO_FORK_DEBUG */
3162 /****************************************************************************
3163 put up a yes/no prompt
3164 ****************************************************************************/
3170 if (!fgets(ans,sizeof(ans)-1,stdin))
3173 if (*ans == 'y' || *ans == 'Y')
3179 /****************************************************************************
3180 read a line from a file with possible \ continuation chars.
3181 Blanks at the start or end of a line are stripped.
3182 The string will be allocated if s2 is NULL
3183 ****************************************************************************/
3184 char *fgets_slash(char *s2,int maxlen,FILE *f)
3189 BOOL start_of_line = True;
3196 maxlen = MIN(maxlen,8);
3197 s = (char *)Realloc(s,maxlen);
3200 if (!s || maxlen < 2) return(NULL);
3204 while (len < maxlen-1)
3212 while (len > 0 && s[len-1] == ' ')
3216 if (len > 0 && s[len-1] == '\\')
3219 start_of_line = True;
3224 if (len <= 0 && !s2)
3226 return(len>0?s:NULL);
3231 start_of_line = False;
3235 if (!s2 && len > maxlen-3)
3238 s = (char *)Realloc(s,maxlen);
3239 if (!s) return(NULL);
3247 /****************************************************************************
3248 set the length of a file from a filedescriptor.
3249 Returns 0 on success, -1 on failure.
3250 ****************************************************************************/
3251 int set_filelen(int fd, long len)
3253 /* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
3254 extend a file with ftruncate. Provide alternate implementation
3257 #if FTRUNCATE_CAN_EXTEND
3258 return ftruncate(fd, len);
3262 long currpos = lseek(fd, 0L, SEEK_CUR);
3266 /* Do an fstat to see if the file is longer than
3267 the requested size (call ftruncate),
3268 or shorter, in which case seek to len - 1 and write 1
3270 if(fstat(fd, &st)<0)
3274 if (S_ISFIFO(st.st_mode)) return 0;
3277 if(st.st_size == len)
3279 if(st.st_size > len)
3280 return ftruncate(fd, len);
3282 if(lseek(fd, len-1, SEEK_SET) != len -1)
3284 if(write(fd, &c, 1)!=1)
3286 /* Seek to where we were */
3287 lseek(fd, currpos, SEEK_SET);
3293 /****************************************************************************
3294 return the byte checksum of some data
3295 ****************************************************************************/
3296 int byte_checksum(char *buf,int len)
3298 unsigned char *p = (unsigned char *)buf;
3308 /****************************************************************************
3309 this is a version of setbuffer() for those machines that only have setvbuf
3310 ****************************************************************************/
3311 void setbuffer(FILE *f,char *buf,int bufsize)
3313 setvbuf(f,buf,_IOFBF,bufsize);
3318 /****************************************************************************
3319 parse out a directory name from a path name. Assumes dos style filenames.
3320 ****************************************************************************/
3321 char *dirname_dos(char *path,char *buf)
3323 char *p = strrchr(path,'\\');
3338 /****************************************************************************
3339 parse out a filename from a path name. Assumes dos style filenames.
3340 ****************************************************************************/
3341 static char *filename_dos(char *path,char *buf)
3343 char *p = strrchr(path,'\\');
3355 /****************************************************************************
3356 expand a pointer to be a particular size
3357 ****************************************************************************/
3358 void *Realloc(void *p,int size)
3364 DEBUG(5,("Realloc asked for 0 bytes\n"));
3369 ret = (void *)malloc(size);
3371 ret = (void *)realloc(p,size);
3374 DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
3380 /****************************************************************************
3382 ****************************************************************************/
3383 char *strdup(char *s)
3387 if (!s) return(NULL);
3388 ret = (char *)malloc((len = strlen(s))+1);
3389 if (!ret) return(NULL);
3390 safe_strcpy(ret,s,len);
3396 /****************************************************************************
3397 Signal handler for SIGPIPE (write on a disconnected socket)
3398 ****************************************************************************/
3401 DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
3405 /****************************************************************************
3406 get my own name and IP
3407 ****************************************************************************/
3408 BOOL get_myname(char *my_name,struct in_addr *ip)
3415 /* get my host name */
3416 if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
3418 DEBUG(0,("gethostname failed\n"));
3423 if ((hp = Get_Hostbyname(hostname)) == 0)
3425 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname));
3431 /* split off any parts after an initial . */
3432 char *p = strchr(hostname,'.');
3435 fstrcpy(my_name,hostname);
3439 putip((char *)ip,(char *)hp->h_addr);
3445 /****************************************************************************
3446 true if two IP addresses are equal
3447 ****************************************************************************/
3448 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
3451 a1 = ntohl(ip1.s_addr);
3452 a2 = ntohl(ip2.s_addr);
3457 /****************************************************************************
3458 open a socket of the specified type, port and address for incoming data
3459 ****************************************************************************/
3460 int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
3463 struct sockaddr_in sock;
3467 /* get my host name */
3468 if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
3469 { DEBUG(0,("gethostname failed\n")); return -1; }
3472 if ((hp = Get_Hostbyname(host_name)) == 0)
3474 DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name));
3478 bzero((char *)&sock,sizeof(sock));
3479 memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
3480 #if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */
3481 sock.sin_len = sizeof(sock);
3483 sock.sin_port = htons( port );
3484 sock.sin_family = hp->h_addrtype;
3485 sock.sin_addr.s_addr = socket_addr;
3486 res = socket(hp->h_addrtype, type, 0);
3488 { DEBUG(0,("socket failed\n")); return -1; }
3492 setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
3495 /* now we've got a socket - we need to bind it */
3496 if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
3499 if (port == SMB_PORT || port == NMB_PORT)
3500 DEBUG(dlevel,("bind failed on port %d socket_addr=%s (%s)\n",
3501 port,inet_ntoa(sock.sin_addr),strerror(errno)));
3504 if (dlevel > 0 && port < 1000)
3507 if (port >= 1000 && port < 9000)
3508 return(open_socket_in(type,port+1,dlevel,socket_addr));
3513 DEBUG(3,("bind succeeded on port %d\n",port));
3519 /****************************************************************************
3520 create an outgoing socket
3521 **************************************************************************/
3522 int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
3524 struct sockaddr_in sock_out;
3526 int connect_loop = 250; /* 250 milliseconds */
3527 int loops = (timeout * 1000) / connect_loop;
3529 /* create a socket to write to */
3530 res = socket(PF_INET, type, 0);
3532 { DEBUG(0,("socket error\n")); return -1; }
3534 if (type != SOCK_STREAM) return(res);
3536 bzero((char *)&sock_out,sizeof(sock_out));
3537 putip((char *)&sock_out.sin_addr,(char *)addr);
3539 sock_out.sin_port = htons( port );
3540 sock_out.sin_family = PF_INET;
3542 /* set it non-blocking */
3543 set_blocking(res,False);
3545 DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
3547 /* and connect it to the destination */
3549 ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
3551 /* Some systems return EAGAIN when they mean EINPROGRESS */
3552 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3553 errno == EAGAIN) && loops--) {
3554 msleep(connect_loop);
3558 if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
3560 DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
3566 if (ret < 0 && errno == EISCONN) {
3573 DEBUG(1,("error connecting to %s:%d (%s)\n",
3574 inet_ntoa(*addr),port,strerror(errno)));
3578 /* set it blocking again */
3579 set_blocking(res,True);
3585 /****************************************************************************
3586 interpret a protocol description string, with a default
3587 ****************************************************************************/
3588 int interpret_protocol(char *str,int def)
3590 if (strequal(str,"NT1"))
3591 return(PROTOCOL_NT1);
3592 if (strequal(str,"LANMAN2"))
3593 return(PROTOCOL_LANMAN2);
3594 if (strequal(str,"LANMAN1"))
3595 return(PROTOCOL_LANMAN1);
3596 if (strequal(str,"CORE"))
3597 return(PROTOCOL_CORE);
3598 if (strequal(str,"COREPLUS"))
3599 return(PROTOCOL_COREPLUS);
3600 if (strequal(str,"CORE+"))
3601 return(PROTOCOL_COREPLUS);
3603 DEBUG(0,("Unrecognised protocol level %s\n",str));
3608 /****************************************************************************
3609 interpret a security level
3610 ****************************************************************************/
3611 int interpret_security(char *str,int def)
3613 if (strequal(str,"SERVER"))
3615 if (strequal(str,"USER"))
3617 if (strequal(str,"SHARE"))
3620 DEBUG(0,("Unrecognised security level %s\n",str));
3626 /****************************************************************************
3627 interpret an internet address or name into an IP address in 4 byte form
3628 ****************************************************************************/
3629 uint32 interpret_addr(char *str)
3634 BOOL pure_address = True;
3636 if (strcmp(str,"0.0.0.0") == 0) return(0);
3637 if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
3639 for (i=0; pure_address && str[i]; i++)
3640 if (!(isdigit(str[i]) || str[i] == '.'))
3641 pure_address = False;
3643 /* if it's in the form of an IP address then get the lib to interpret it */
3645 res = inet_addr(str);
3647 /* otherwise assume it's a network name of some sort and use
3649 if ((hp = Get_Hostbyname(str)) == 0) {
3650 DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
3653 if(hp->h_addr == NULL) {
3654 DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
3657 putip((char *)&res,(char *)hp->h_addr);
3660 if (res == (uint32)-1) return(0);
3665 /*******************************************************************
3666 a convenient addition to interpret_addr()
3667 ******************************************************************/
3668 struct in_addr *interpret_addr2(char *str)
3670 static struct in_addr ret;
3671 uint32 a = interpret_addr(str);
3676 /*******************************************************************
3677 check if an IP is the 0.0.0.0
3678 ******************************************************************/
3679 BOOL zero_ip(struct in_addr ip)
3682 putip((char *)&a,(char *)&ip);
3687 /*******************************************************************
3688 matchname - determine if host name matches IP address
3689 ******************************************************************/
3690 static BOOL matchname(char *remotehost,struct in_addr addr)
3695 if ((hp = Get_Hostbyname(remotehost)) == 0) {
3696 DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
3701 * Make sure that gethostbyname() returns the "correct" host name.
3702 * Unfortunately, gethostbyname("localhost") sometimes yields
3703 * "localhost.domain". Since the latter host name comes from the
3704 * local DNS, we just have to trust it (all bets are off if the local
3705 * DNS is perverted). We always check the address list, though.
3708 if (strcasecmp(remotehost, hp->h_name)
3709 && strcasecmp(remotehost, "localhost")) {
3710 DEBUG(0,("host name/name mismatch: %s != %s",
3711 remotehost, hp->h_name));
3715 /* Look up the host address in the address list we just got. */
3716 for (i = 0; hp->h_addr_list[i]; i++) {
3717 if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
3722 * The host name does not map to the original host address. Perhaps
3723 * someone has compromised a name server. More likely someone botched
3724 * it, but that could be dangerous, too.
3727 DEBUG(0,("host name/address mismatch: %s != %s",
3728 inet_ntoa(addr), hp->h_name));
3732 /*******************************************************************
3733 Reset the 'done' variables so after a client process is created
3734 from a fork call these calls will be re-done. This should be
3735 expanded if more variables need reseting.
3736 ******************************************************************/
3738 static BOOL global_client_name_done = False;
3739 static BOOL global_client_addr_done = False;
3741 void reset_globals_after_fork(void)
3743 global_client_name_done = False;
3744 global_client_addr_done = False;
3747 * Re-seed the random crypto generator, so all smbd's
3748 * started from the same parent won't generate the same
3752 unsigned char dummy;
3753 generate_random_buffer( &dummy, 1, True);
3757 /*******************************************************************
3758 return the DNS name of the client
3759 ******************************************************************/
3760 char *client_name(int fd)
3763 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3764 int length = sizeof(sa);
3765 static pstring name_buf;
3767 static int last_fd=-1;
3769 if (global_client_name_done && last_fd == fd)
3773 global_client_name_done = False;
3775 pstrcpy(name_buf,"UNKNOWN");
3781 if (getpeername(fd, &sa, &length) < 0) {
3782 DEBUG(0,("getpeername failed\n"));
3786 /* Look up the remote host name. */
3787 if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
3788 sizeof(sockin->sin_addr),
3790 DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
3791 StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
3793 StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
3794 if (!matchname(name_buf, sockin->sin_addr)) {
3795 DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
3796 pstrcpy(name_buf,"UNKNOWN");
3799 global_client_name_done = True;
3803 /*******************************************************************
3804 return the IP addr of the client as a string
3805 ******************************************************************/
3806 char *client_addr(int fd)
3809 struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
3810 int length = sizeof(sa);
3811 static fstring addr_buf;
3812 static int last_fd = -1;
3814 if (global_client_addr_done && fd == last_fd)
3818 global_client_addr_done = False;
3820 fstrcpy(addr_buf,"0.0.0.0");
3826 if (getpeername(fd, &sa, &length) < 0) {
3827 DEBUG(0,("getpeername failed\n"));
3831 fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
3833 global_client_addr_done = True;
3837 /*******************************************************************
3838 Patch from jkf@soton.ac.uk
3839 Split Luke's automount_server into YP lookup and string splitter
3840 so can easily implement automount_path().
3841 As we may end up doing both, cache the last YP result.
3842 *******************************************************************/
3844 #if (defined(NETGROUP) && defined(AUTOMOUNT))
3846 static char *automount_lookup(char *user_name)
3848 static fstring last_key = "";
3849 static pstring last_value = "";
3851 char *nis_map = (char *)lp_nis_home_map_name();
3853 char nis_domain[NIS_MAXNAMELEN + 1];
3854 char buffer[NIS_MAXATTRVAL + 1];
3859 strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
3860 nis_domain[NIS_MAXNAMELEN] = '\0';
3862 DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
3864 if (strcmp(user_name, last_key))
3866 slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
3867 DEBUG(5, ("NIS+ querystring: %s\n", buffer));
3869 if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
3871 if (result->status != NIS_SUCCESS)
3873 DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
3874 fstrcpy(last_key, ""); pstrcpy(last_value, "");
3878 object = result->objects.objects_val;
3879 if (object->zo_data.zo_type == ENTRY_OBJ)
3881 entry = &object->zo_data.objdata_u.en_data;
3882 DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
3883 DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
3885 pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
3886 string_sub(last_value, "&", user_name);
3887 fstrcpy(last_key, user_name);
3891 nis_freeresult(result);
3893 DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
3896 #else /* NISPLUS_HOME */
3897 static char *automount_lookup(char *user_name)
3899 static fstring last_key = "";
3900 static pstring last_value = "";
3902 int nis_error; /* returned by yp all functions */
3903 char *nis_result; /* yp_match inits this */
3904 int nis_result_len; /* and set this */
3905 char *nis_domain; /* yp_get_default_domain inits this */
3906 char *nis_map = (char *)lp_nis_home_map_name();
3908 if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
3910 DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
3914 DEBUG(5, ("NIS Domain: %s\n", nis_domain));
3916 if (!strcmp(user_name, last_key))
3918 nis_result = last_value;
3919 nis_result_len = strlen(last_value);
3924 if ((nis_error = yp_match(nis_domain, nis_map,
3925 user_name, strlen(user_name),
3926 &nis_result, &nis_result_len)) != 0)
3928 DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
3929 yperr_string(nis_error), user_name, nis_map));
3931 if (!nis_error && nis_result_len >= sizeof(pstring))
3933 nis_result_len = sizeof(pstring)-1;
3935 fstrcpy(last_key, user_name);
3936 strncpy(last_value, nis_result, nis_result_len);
3937 last_value[nis_result_len] = '\0';
3940 DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
3943 #endif /* NISPLUS_HOME */
3946 /*******************************************************************
3947 Patch from jkf@soton.ac.uk
3948 This is Luke's original function with the NIS lookup code
3949 moved out to a separate function.
3950 *******************************************************************/
3952 char *automount_server(char *user_name)
3954 static pstring server_name;
3956 /* use the local machine name as the default */
3957 /* this will be the default if AUTOMOUNT is not used or fails */
3958 pstrcpy(server_name, local_machine);
3960 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3962 if (lp_nis_home_map())
3964 int home_server_len;
3965 char *automount_value = automount_lookup(user_name);
3966 home_server_len = strcspn(automount_value,":");
3967 DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
3968 if (home_server_len > sizeof(pstring))
3970 home_server_len = sizeof(pstring);
3972 strncpy(server_name, automount_value, home_server_len);
3973 server_name[home_server_len] = '\0';
3977 DEBUG(4,("Home server: %s\n", server_name));
3982 /*******************************************************************
3983 Patch from jkf@soton.ac.uk
3984 Added this to implement %p (NIS auto-map version of %H)
3985 *******************************************************************/
3987 char *automount_path(char *user_name)
3989 static pstring server_path;
3991 /* use the passwd entry as the default */
3992 /* this will be the default if AUTOMOUNT is not used or fails */
3993 /* pstrcpy() copes with get_home_dir() returning NULL */
3994 pstrcpy(server_path, get_home_dir(user_name));
3996 #if (defined(NETGROUP) && defined (AUTOMOUNT))
3998 if (lp_nis_home_map())
4000 char *home_path_start;
4001 char *automount_value = automount_lookup(user_name);
4002 home_path_start = strchr(automount_value,':');
4003 if (home_path_start != NULL)
4005 DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
4006 home_path_start?(home_path_start+1):""));
4007 pstrcpy(server_path, home_path_start+1);
4012 DEBUG(4,("Home server path: %s\n", server_path));
4018 /*******************************************************************
4019 sub strings with useful parameters
4020 Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
4021 Paul Rippin <pr3245@nopc.eurostat.cec.be>
4022 ********************************************************************/
4023 void standard_sub_basic(char *str)
4027 struct passwd *pass;
4028 char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
4030 for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
4036 if ((pass = Get_Pwnam(username,False))!=NULL)
4038 string_sub(p,"%G",gidtoname(pass->pw_gid));
4046 case 'N' : string_sub(p,"%N", automount_server(username)); break;
4047 case 'I' : string_sub(p,"%I", client_addr(Client)); break;
4048 case 'L' : string_sub(p,"%L", local_machine); break;
4049 case 'M' : string_sub(p,"%M", client_name(Client)); break;
4050 case 'R' : string_sub(p,"%R", remote_proto); break;
4051 case 'T' : string_sub(p,"%T", timestring()); break;
4052 case 'U' : string_sub(p,"%U", username); break;
4053 case 'a' : string_sub(p,"%a", remote_arch); break;
4056 slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
4057 string_sub(p,"%d", pidstr);
4060 case 'h' : string_sub(p,"%h", myhostname); break;
4061 case 'm' : string_sub(p,"%m", remote_machine); break;
4062 case 'v' : string_sub(p,"%v", VERSION); break;
4063 case '$' : /* Expand environment variables */
4065 /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
4076 if ((q = strchr(p,')')) == NULL)
4078 DEBUG(0,("standard_sub_basic: Unterminated environment \
4079 variable [%s]\n", p));
4085 copylen = MIN((q-r),(sizeof(envname)-1));
4086 strncpy(envname,r,copylen);
4087 envname[copylen] = '\0';
4089 if ((envval = getenv(envname)) == NULL)
4091 DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n",
4097 copylen = MIN((q+1-p),(sizeof(envname)-1));
4098 strncpy(envname,p,copylen);
4099 envname[copylen] = '\0';
4100 string_sub(p,envname,envval);
4103 case '\0': p++; break; /* don't run off end if last character is % */
4104 default : p+=2; break;
4110 /*******************************************************************
4111 are two IPs on the same subnet?
4112 ********************************************************************/
4113 BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
4115 uint32 net1,net2,nmask;
4117 nmask = ntohl(mask.s_addr);
4118 net1 = ntohl(ip1.s_addr);
4119 net2 = ntohl(ip2.s_addr);
4121 return((net1 & nmask) == (net2 & nmask));
4125 /*******************************************************************
4126 write a string in unicoode format
4127 ********************************************************************/
4128 int PutUniCode(char *dst,char *src)
4132 dst[ret++] = src[0];
4141 /****************************************************************************
4142 a wrapper for gethostbyname() that tries with all lower and all upper case
4143 if the initial name fails
4144 ****************************************************************************/
4145 struct hostent *Get_Hostbyname(char *name)
4147 char *name2 = strdup(name);
4148 struct hostent *ret;
4152 DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
4158 * This next test is redundent and causes some systems (with
4159 * broken isalnum() calls) problems.
4164 if (!isalnum(*name2))
4171 ret = sys_gethostbyname(name2);
4178 /* try with all lowercase */
4180 ret = sys_gethostbyname(name2);
4187 /* try with all uppercase */
4189 ret = sys_gethostbyname(name2);
4196 /* nothing works :-( */
4202 /****************************************************************************
4203 check if a process exists. Does this work on all unixes?
4204 ****************************************************************************/
4205 BOOL process_exists(int pid)
4207 return(kill(pid,0) == 0 || errno != ESRCH);
4211 /*******************************************************************
4212 turn a uid into a user name
4213 ********************************************************************/
4214 char *uidtoname(int uid)
4216 static char name[40];
4217 struct passwd *pass = getpwuid(uid);
4218 if (pass) return(pass->pw_name);
4219 slprintf(name, sizeof(name) - 1, "%d",uid);
4223 /*******************************************************************
4224 turn a gid into a group name
4225 ********************************************************************/
4226 char *gidtoname(int gid)
4228 static char name[40];
4229 struct group *grp = getgrgid(gid);
4230 if (grp) return(grp->gr_name);
4231 slprintf(name,sizeof(name) - 1, "%d",gid);
4235 /*******************************************************************
4237 ********************************************************************/
4238 void BlockSignals(BOOL block,int signum)
4241 int block_mask = sigmask(signum);
4242 static int oldmask = 0;
4244 oldmask = sigblock(block_mask);
4246 sigsetmask(oldmask);
4247 #elif defined(USE_SIGPROCMASK)
4250 sigaddset(&set,signum);
4251 sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
4256 /*******************************************************************
4257 my own panic function - not suitable for general use
4258 ********************************************************************/
4259 void ajt_panic(void)
4261 system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT");
4266 #define DIRECT direct
4268 #define DIRECT dirent
4271 /*******************************************************************
4272 a readdir wrapper which just returns the file name
4273 also return the inode number if requested
4274 ********************************************************************/
4275 char *readdirname(void *p)
4280 if (!p) return(NULL);
4282 ptr = (struct DIRECT *)readdir(p);
4283 if (!ptr) return(NULL);
4285 dname = ptr->d_name;
4288 if (telldir(p) < 0) return(NULL);
4292 /* this handles a broken compiler setup, causing a mixture
4293 of BSD and SYSV headers and libraries */
4295 static BOOL broken_readdir = False;
4296 if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
4298 DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
4299 broken_readdir = True;
4308 pstrcpy(buf, dname);
4309 unix_to_dos(buf, True);
4316 /*******************************************************************
4317 Utility function used to decide if the last component
4318 of a path matches a (possibly wildcarded) entry in a namelist.
4319 ********************************************************************/
4321 BOOL is_in_path(char *name, name_compare_entry *namelist)
4323 pstring last_component;
4326 DEBUG(8, ("is_in_path: %s\n", name));
4328 /* if we have no list it's obviously not in the path */
4329 if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
4331 DEBUG(8,("is_in_path: no name list.\n"));
4335 /* Get the last component of the unix name. */
4336 p = strrchr(name, '/');
4337 strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
4338 last_component[sizeof(last_component)-1] = '\0';
4340 for(; namelist->name != NULL; namelist++)
4342 if(namelist->is_wild)
4344 /* look for a wildcard match. */
4345 if (mask_match(last_component, namelist->name, case_sensitive, False))
4347 DEBUG(8,("is_in_path: mask match succeeded\n"));
4353 if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
4354 (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
4356 DEBUG(8,("is_in_path: match succeeded\n"));
4361 DEBUG(8,("is_in_path: match not found\n"));
4366 /*******************************************************************
4367 Strip a '/' separated list into an array of
4368 name_compare_enties structures suitable for
4369 passing to is_in_path(). We do this for
4370 speed so we can pre-parse all the names in the list
4371 and don't do it for each call to is_in_path().
4372 namelist is modified here and is assumed to be
4373 a copy owned by the caller.
4374 We also check if the entry contains a wildcard to
4375 remove a potentially expensive call to mask_match
4377 ********************************************************************/
4379 void set_namearray(name_compare_entry **ppname_array, char *namelist)
4382 char *nameptr = namelist;
4383 int num_entries = 0;
4386 (*ppname_array) = NULL;
4388 if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
4391 /* We need to make two passes over the string. The
4392 first to count the number of elements, the second
4397 if ( *nameptr == '/' )
4399 /* cope with multiple (useless) /s) */
4403 /* find the next / */
4404 name_end = strchr(nameptr, '/');
4406 /* oops - the last check for a / didn't find one. */
4407 if (name_end == NULL)
4410 /* next segment please */
4411 nameptr = name_end + 1;
4415 if(num_entries == 0)
4418 if(( (*ppname_array) = (name_compare_entry *)malloc(
4419 (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
4421 DEBUG(0,("set_namearray: malloc fail\n"));
4425 /* Now copy out the names */
4430 if ( *nameptr == '/' )
4432 /* cope with multiple (useless) /s) */
4436 /* find the next / */
4437 if ((name_end = strchr(nameptr, '/')) != NULL)
4442 /* oops - the last check for a / didn't find one. */
4443 if(name_end == NULL)
4446 (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
4447 (strchr( nameptr, '*')!=NULL));
4448 if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
4450 DEBUG(0,("set_namearray: malloc fail (1)\n"));
4454 /* next segment please */
4455 nameptr = name_end + 1;
4459 (*ppname_array)[i].name = NULL;
4464 /****************************************************************************
4465 routine to free a namearray.
4466 ****************************************************************************/
4468 void free_namearray(name_compare_entry *name_array)
4473 if(name_array->name != NULL)
4474 free(name_array->name);
4476 free((char *)name_array);
4479 /****************************************************************************
4480 routine to do file locking
4481 ****************************************************************************/
4482 BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
4489 uint32 mask = 0xC0000000;
4491 /* make sure the count is reasonable, we might kill the lockd otherwise */
4494 /* the offset is often strange - remove 2 of its bits if either of
4495 the top two bits are set. Shift the top ones by two bits. This
4496 still allows OLE2 apps to operate, but should stop lockd from
4498 if ((offset & mask) != 0)
4499 offset = (offset & ~mask) | ((offset & mask) >> 2);
4501 uint32 mask = ((unsigned)1<<31);
4503 /* interpret negative counts as large numbers */
4507 /* no negative offsets */
4510 /* count + offset must be in range */
4511 while ((offset < 0 || (offset + count < 0)) && mask)
4519 DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
4522 lock.l_whence = SEEK_SET;
4523 lock.l_start = (int)offset;
4524 lock.l_len = (int)count;
4529 ret = fcntl(fd,op,&lock);
4532 DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
4538 (lock.l_type != F_UNLCK) &&
4539 (lock.l_pid != 0) &&
4540 (lock.l_pid != getpid()))
4542 DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
4546 /* it must be not locked or locked by me */
4550 /* a lock set or unset */
4553 DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
4554 offset,count,op,type,strerror(errno)));
4556 /* perhaps it doesn't support this sort of locking?? */
4557 if (errno == EINVAL)
4559 DEBUG(3,("locking not supported? returning True\n"));
4566 /* everything went OK */
4567 DEBUG(8,("Lock call successful\n"));
4575 /*******************************************************************
4576 lock a file - returning a open file descriptor or -1 on failure
4577 The timeout is in seconds. 0 means no timeout
4578 ********************************************************************/
4579 int file_lock(char *name,int timeout)
4581 int fd = open(name,O_RDWR|O_CREAT,0666);
4583 if (fd < 0) return(-1);
4586 if (timeout) t = time(NULL);
4587 while (!timeout || (time(NULL)-t < timeout)) {
4588 if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
4589 msleep(LOCK_RETRY_TIMEOUT);
4597 /*******************************************************************
4598 unlock a file locked by file_lock
4599 ********************************************************************/
4600 void file_unlock(int fd)
4604 fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
4609 /*******************************************************************
4610 is the name specified one of my netbios names
4611 returns true is it is equal, false otherwise
4612 ********************************************************************/
4613 BOOL is_myname(char *s)
4618 for (n=0; my_netbios_names[n]; n++) {
4619 if (strequal(my_netbios_names[n], s))
4622 DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
4626 /*******************************************************************
4627 set the horrid remote_arch string based on an enum.
4628 ********************************************************************/
4629 void set_remote_arch(enum remote_arch_types type)
4635 fstrcpy(remote_arch, "WfWg");
4638 fstrcpy(remote_arch, "OS2");
4641 fstrcpy(remote_arch, "Win95");
4644 fstrcpy(remote_arch, "WinNT");
4647 fstrcpy(remote_arch,"Samba");
4650 ra_type = RA_UNKNOWN;
4651 fstrcpy(remote_arch, "UNKNOWN");
4656 /*******************************************************************
4657 Get the remote_arch type.
4658 ********************************************************************/
4659 enum remote_arch_types get_remote_arch(void)
4665 /*******************************************************************
4666 skip past some unicode strings in a buffer
4667 ********************************************************************/
4668 char *skip_unicode_string(char *buf,int n)
4679 /*******************************************************************
4680 Return a ascii version of a unicode string
4681 Hack alert: uses fixed buffer(s) and only handles ascii strings
4682 ********************************************************************/
4684 char *unistrn2(uint16 *buf, int len)
4686 static char lbufs[8][MAXUNI];
4688 char *lbuf = lbufs[nexti];
4691 nexti = (nexti+1)%8;
4693 DEBUG(10, ("unistrn2: "));
4695 for (p = lbuf; *buf && p-lbuf < MAXUNI-2 && len > 0; len--, p++, buf++)
4697 DEBUG(10, ("%4x ", *buf));
4707 /*******************************************************************
4708 Return a ascii version of a unicode string
4709 Hack alert: uses fixed buffer(s) and only handles ascii strings
4710 ********************************************************************/
4712 char *unistr2(uint16 *buf)
4714 static char lbufs[8][MAXUNI];
4716 char *lbuf = lbufs[nexti];
4719 nexti = (nexti+1)%8;
4721 DEBUG(10, ("unistr2: "));
4723 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
4725 DEBUG(10, ("%4x ", *buf));
4735 /*******************************************************************
4736 create a null-terminated unicode string from a null-terminated ascii string.
4737 return number of unicode chars copied, excluding the null character.
4739 only handles ascii strings
4740 ********************************************************************/
4742 int struni2(uint16 *p, char *buf)
4746 if (p == NULL) return 0;
4748 DEBUG(10, ("struni2: "));
4752 for (; *buf && len < MAXUNI-2; len++, p++, buf++)
4754 DEBUG(10, ("%2x ", *buf));
4766 /*******************************************************************
4767 Return a ascii version of a unicode string
4768 Hack alert: uses fixed buffer(s) and only handles ascii strings
4769 ********************************************************************/
4771 char *unistr(char *buf)
4773 static char lbufs[8][MAXUNI];
4775 char *lbuf = lbufs[nexti];
4778 nexti = (nexti+1)%8;
4780 for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
4788 /*******************************************************************
4789 strncpy for unicode strings
4790 ********************************************************************/
4791 int unistrncpy(char *dst, char *src, int len)
4795 while (*src && len > 0)
4809 /*******************************************************************
4810 strcpy for unicode strings. returns length (in num of wide chars)
4811 ********************************************************************/
4812 int unistrcpy(char *dst, char *src)
4828 /*******************************************************************
4829 safe string copy into a known length string. maxlength does not
4830 include the terminating zero.
4831 ********************************************************************/
4832 char *safe_strcpy(char *dest, char *src, int maxlength)
4837 DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
4848 if (len > maxlength) {
4849 DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
4850 len-maxlength, src));
4854 memcpy(dest, src, len);
4859 /*******************************************************************
4860 safe string cat into a string. maxlength does not
4861 include the terminating zero.
4862 ********************************************************************/
4863 char *safe_strcat(char *dest, char *src, int maxlength)
4865 int src_len, dest_len;
4868 DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
4876 src_len = strlen(src);
4877 dest_len = strlen(dest);
4879 if (src_len + dest_len > maxlength) {
4880 DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
4881 src_len + dest_len - maxlength, src));
4882 src_len = maxlength - dest_len;
4885 memcpy(&dest[dest_len], src, src_len);
4886 dest[dest_len + src_len] = 0;
4890 /*******************************************************************
4891 align a pointer to a multiple of 4 bytes
4892 ********************************************************************/
4893 char *align4(char *q, char *base)
4897 q += 4 - ((q - base) & 3);
4902 /*******************************************************************
4903 align a pointer to a multiple of 2 bytes
4904 ********************************************************************/
4905 char *align2(char *q, char *base)
4914 /*******************************************************************
4915 align a pointer to a multiple of align_offset bytes. looks like it
4916 will work for offsets of 0, 2 and 4...
4917 ********************************************************************/
4918 char *align_offset(char *q, char *base, int align_offset_len)
4920 int mod = ((q - base) & (align_offset_len-1));
4921 if (align_offset_len != 0 && mod != 0)
4923 q += align_offset_len - mod;
4928 void print_asc(int level, unsigned char *buf,int len)
4932 DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
4935 void dump_data(int level,char *buf1,int len)
4937 unsigned char *buf = (unsigned char *)buf1;
4941 DEBUG(level,("[%03X] ",i));
4943 DEBUG(level,("%02X ",(int)buf[i]));
4945 if (i%8 == 0) DEBUG(level,(" "));
4947 print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
4948 print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
4949 if (i<len) DEBUG(level,("[%03X] ",i));
4957 if (n>8) DEBUG(level,(" "));
4958 while (n--) DEBUG(level,(" "));
4961 print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
4963 if (n>0) print_asc(level,&buf[i-n],n);
4964 DEBUG(level,("\n"));
4968 char *tab_depth(int depth)
4970 static pstring spaces;
4971 memset(spaces, ' ', depth * 4);
4972 spaces[depth * 4] = 0;
4976 /*****************************************************************
4977 Convert a SID to an ascii string.
4978 *****************************************************************/
4980 char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
4984 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
4985 uint32 ia = (sid->id_auth[5]) +
4986 (sid->id_auth[4] << 8 ) +
4987 (sid->id_auth[3] << 16) +
4988 (sid->id_auth[2] << 24);
4990 slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
4992 for (i = 0; i < sid->num_auths; i++)
4994 slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
4995 pstrcat(sidstr_out, subauth);
4998 DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
5002 /*****************************************************************
5003 Convert a string to a SID. Returns True on success, False on fail.
5004 *****************************************************************/
5006 BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
5010 /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
5013 memset((char *)sidout, '\0', sizeof(DOM_SID));
5015 if(StrnCaseCmp( sidstr, "S-", 2)) {
5016 DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
5021 if(!next_token(&p, tok, "-")) {
5022 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5026 /* Get the revision number. */
5027 sidout->sid_rev_num = atoi(tok);
5029 if(!next_token(&p, tok, "-")) {
5030 DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
5034 /* identauth in decimal should be < 2^32 */
5037 /* NOTE - the ia value is in big-endian format. */
5038 sidout->id_auth[0] = 0;
5039 sidout->id_auth[1] = 0;
5040 sidout->id_auth[2] = (ia & 0xff000000) >> 24;
5041 sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
5042 sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
5043 sidout->id_auth[5] = (ia & 0x000000ff);
5045 sidout->num_auths = 0;
5047 while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) {
5049 * NOTE - the subauths are in native machine-endian format. They
5050 * are converted to little-endian when linearized onto the wire.
5052 sidout->sub_auths[sidout->num_auths++] = atoi(tok);
5055 DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));