X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source%2Flib%2Futil.c;h=8d1f61931890fc54965d7ffdd7704ae8cc16dab7;hb=3bda7ac417107a7b01d91805ca71c4330657ed21;hp=365a765174242ecb19e14c7d25022f53fc65e813;hpb=e58ab3bbe6e939ba678ad5482e58e0191c8dcbcb;p=samba.git diff --git a/source/lib/util.c b/source/lib/util.c index 365a7651742..8d1f6193189 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -21,9 +21,20 @@ #include "includes.h" -#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) +#ifdef NISPLUS_HOME +#include +#else #include "rpcsvc/ypclnt.h" #endif +#endif + +#ifdef WITH_SSL +#include +#undef Realloc /* SSLeay defines this and samba has a function of this name */ +extern SSL *ssl; +extern int sslFd; +#endif /* WITH_SSL */ pstring scope = ""; @@ -59,7 +70,7 @@ int trans_num = 0; int case_default = CASE_LOWER; pstring debugf = ""; -int syslog_level; +int syslog_level = 0; /* the following control case operations - they are put here so the client can link easily */ @@ -82,8 +93,8 @@ pstring samlogon_user=""; BOOL sam_logon_in_ssb = False; -pstring myname = ""; -fstring myworkgroup = ""; +pstring global_myname = ""; +fstring global_myworkgroup = ""; char **my_netbios_names; int smb_read_error = 0; @@ -93,9 +104,9 @@ static BOOL stdout_logging = False; static char *filename_dos(char *path,char *buf); #if defined(SIGUSR2) -/**************************************************************************** ** +/****************************************************************************** catch a sigusr2 - decrease the debug log level. - **************************************************************************** */ + *****************************************************************************/ int sig_usr2(void) { BlockSignals( True, SIGUSR2); @@ -108,17 +119,16 @@ int sig_usr2(void) DEBUG( 0, ( "Got SIGUSR2 set debug level to %d.\n", DEBUGLEVEL ) ); BlockSignals( False, SIGUSR2); -#ifndef DONT_REINSTALL_SIG - signal(SIGUSR2, SIGNAL_CAST sig_usr2); -#endif + CatchSignal(SIGUSR2, SIGNAL_CAST sig_usr2); + return(0); } #endif /* SIGUSR1 */ #if defined(SIGUSR1) -/**************************************************************************** ** +/****************************************************************************** catch a sigusr1 - increase the debug log level. - **************************************************************************** */ + *****************************************************************************/ int sig_usr1(void) { BlockSignals( True, SIGUSR1); @@ -131,9 +141,7 @@ int sig_usr1(void) DEBUG( 0, ( "Got SIGUSR1 set debug level to %d.\n", DEBUGLEVEL ) ); BlockSignals( False, SIGUSR1); -#ifndef DONT_REINSTALL_SIG - signal(SIGUSR1, SIGNAL_CAST sig_usr1); -#endif + CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1); return(0); } #endif /* SIGUSR1 */ @@ -144,7 +152,7 @@ int sig_usr1(void) ******************************************************************/ void setup_logging(char *pname,BOOL interactive) { -#ifdef SYSLOG +#ifdef WITH_SYSLOG if (!interactive) { char *p = strrchr(pname,'/'); if (p) pname = p+1; @@ -173,57 +181,84 @@ void reopen_logs(void) pstring fname; if (DEBUGLEVEL > 0) - { - strcpy(fname,debugf); - if (lp_loaded() && (*lp_logfile())) - strcpy(fname,lp_logfile()); + { + pstrcpy(fname,debugf); + if (lp_loaded() && (*lp_logfile())) + pstrcpy(fname,lp_logfile()); - if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) - { - int oldumask = umask(022); - strcpy(debugf,fname); - if (dbf) fclose(dbf); - if (append_log) - dbf = fopen(debugf,"a"); - else - dbf = fopen(debugf,"w"); - if (dbf) setbuf(dbf,NULL); - umask(oldumask); - } + if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL)) + { + int oldumask = umask(022); + pstrcpy(debugf,fname); + if (dbf) + fclose(dbf); + if (append_log) + dbf = fopen(debugf,"a"); + else + dbf = fopen(debugf,"w"); + /* + * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De + * to fix problem where smbd's that generate less + * than 100 messages keep growing the log. + */ + force_check_log_size(); + if (dbf) + setbuf(dbf,NULL); + umask(oldumask); } + } else + { + if (dbf) { - if (dbf) - { - fclose(dbf); - dbf = NULL; - } + fclose(dbf); + dbf = NULL; } + } } +/******************************************************************* + Number of debug messages that have been output. + Used to check log size. +********************************************************************/ + +static int debug_count=0; + +/******************************************************************* + Force a check of the log size. +********************************************************************/ + +void force_check_log_size(void) +{ + debug_count = 100; +} /******************************************************************* -check if the log has grown too big + Check if the log has grown too big ********************************************************************/ + static void check_log_size(void) { - static int debug_count=0; int maxlog; struct stat st; - if (debug_count++ < 100 || getuid() != 0) return; + if (debug_count++ < 100 || getuid() != 0) + return; maxlog = lp_max_log_size() * 1024; - if (!dbf || maxlog <= 0) return; + if (!dbf || maxlog <= 0) + return; if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) { - fclose(dbf); dbf = NULL; + fclose(dbf); + dbf = NULL; reopen_logs(); if (dbf && file_size(debugf) > maxlog) { pstring name; - fclose(dbf); dbf = NULL; - sprintf(name,"%s.old",debugf); - sys_rename(debugf,name); + fclose(dbf); + dbf = NULL; + slprintf(name,sizeof(name)-1,"%s.old",debugf); + rename(debugf,name); reopen_logs(); } } @@ -235,7 +270,7 @@ static void check_log_size(void) write an debug message on the debugfile. This is called by the DEBUG macro ********************************************************************/ -#ifdef __STDC__ +#ifdef HAVE_STDARG_H int Debug1(char *format_str, ...) { #else @@ -248,7 +283,7 @@ va_dcl int old_errno = errno; if (stdout_logging) { -#ifdef __STDC__ +#ifdef HAVE_STDARG_H va_start(ap, format_str); #else va_start(ap); @@ -260,13 +295,16 @@ va_dcl return(0); } -#ifdef SYSLOG +#ifdef WITH_SYSLOG if (!lp_syslog_only()) #endif { if (!dbf) { int oldumask = umask(022); - dbf = fopen(debugf,"w"); + if(append_log) + dbf = fopen(debugf,"a"); + else + dbf = fopen(debugf,"w"); umask(oldumask); if (dbf) { setbuf(dbf,NULL); @@ -277,7 +315,7 @@ va_dcl } } -#ifdef SYSLOG +#ifdef WITH_SYSLOG if (syslog_level < lp_syslog()) { /* @@ -300,13 +338,13 @@ va_dcl else priority = priority_map[syslog_level]; -#ifdef __STDC__ +#ifdef HAVE_STDARG_H va_start(ap, format_str); #else va_start(ap); format_str = va_arg(ap,char *); #endif - vsprintf(msgbuf, format_str, ap); + vslprintf(msgbuf, sizeof(msgbuf)-1,format_str, ap); va_end(ap); msgbuf[255] = '\0'; @@ -314,11 +352,11 @@ va_dcl } #endif -#ifdef SYSLOG +#ifdef WITH_SYSLOG if (!lp_syslog_only()) #endif { -#ifdef __STDC__ +#ifdef HAVE_STDARG_H va_start(ap, format_str); #else va_start(ap); @@ -442,66 +480,20 @@ char **toktocliplist(int *ctok, char *sep) return ret; } -#ifndef HAVE_MEMMOVE -/******************************************************************* -safely copies memory, ensuring no overlap problems. -this is only used if the machine does not have it's own memmove(). -this is not the fastest algorithm in town, but it will do for our -needs. -********************************************************************/ -void *MemMove(void *dest,void *src,int size) -{ - unsigned long d,s; - int i; - if (dest==src || !size) return(dest); - - d = (unsigned long)dest; - s = (unsigned long)src; - if ((d >= (s+size)) || (s >= (d+size))) { - /* no overlap */ - memcpy(dest,src,size); - return(dest); - } - - if (d < s) - { - /* we can forward copy */ - if (s-d >= sizeof(int) && - !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=0;i= sizeof(int) && - !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) { - /* do it all as words */ - int *idest = (int *)dest; - int *isrc = (int *)src; - size /= sizeof(int); - for (i=size-1;i>=0;i--) idest[i] = isrc[i]; - } else { - /* simplest */ - char *cdest = (char *)dest; - char *csrc = (char *)src; - for (i=size-1;i>=0;i--) cdest[i] = csrc[i]; - } - } - return(dest); -} -#endif +/* ************************************************************************* ** + * Duplicate a block of memory. + * ************************************************************************* ** + */ +void *mem_dup( void *from, int size ) + { + void *tmp; + tmp = malloc( size ); + if( NULL != tmp ) + (void)memcpy( tmp, from, size ); + return( tmp ); + } /* mem_dup */ /**************************************************************************** prompte a dptr (to make it recently used) @@ -574,7 +566,7 @@ set user socket options ****************************************************************************/ void set_socket_options(int fd, char *options) { - string tok; + fstring tok; while (next_token(&options,tok," \t,")) { @@ -632,6 +624,10 @@ void set_socket_options(int fd, char *options) ****************************************************************************/ void close_sockets(void ) { +#ifdef WITH_SSL + sslutil_disconnect(Client); +#endif /* WITH_SSL */ + close(Client); Client = 0; } @@ -760,7 +756,7 @@ int name_mangle( char *In, char *Out, char name_type ) if( '*' == In[0] ) buf[0] = '*'; else - (void)sprintf( buf, "%-15.15s%c", In, name_type ); + (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); /* Place the length of the first field into the output buffer. */ p[0] = 32; @@ -862,16 +858,16 @@ return a string representing an attribute for a file ********************************************************************/ char *attrib_string(int mode) { - static char attrstr[10]; + static fstring attrstr; attrstr[0] = 0; - if (mode & aVOLID) strcat(attrstr,"V"); - if (mode & aDIR) strcat(attrstr,"D"); - if (mode & aARCH) strcat(attrstr,"A"); - if (mode & aHIDDEN) strcat(attrstr,"H"); - if (mode & aSYSTEM) strcat(attrstr,"S"); - if (mode & aRONLY) strcat(attrstr,"R"); + if (mode & aVOLID) fstrcat(attrstr,"V"); + if (mode & aDIR) fstrcat(attrstr,"D"); + if (mode & aARCH) fstrcat(attrstr,"A"); + if (mode & aHIDDEN) fstrcat(attrstr,"H"); + if (mode & aSYSTEM) fstrcat(attrstr,"S"); + if (mode & aRONLY) fstrcat(attrstr,"R"); return(attrstr); } @@ -887,6 +883,15 @@ int StrCaseCmp(char *s, char *t) asynchronous upper to lower mapping. */ #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -951,6 +956,15 @@ int StrnCaseCmp(char *s, char *t, int n) asynchronous upper to lower mapping. */ #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1058,6 +1072,15 @@ void strlower(char *s) while (*s) { #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1081,9 +1104,15 @@ void strlower(char *s) else #endif /* KANJI_WIN95_COMPATIBILITY */ { - if (isupper(*s)) - *s = tolower(*s); - s++; + int skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; + else + { + if (isupper(*s)) + *s = tolower(*s); + s++; + } } } } @@ -1096,6 +1125,15 @@ void strupper(char *s) while (*s) { #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1119,9 +1157,15 @@ void strupper(char *s) else #endif /* KANJI_WIN95_COMPATIBILITY */ { - if (islower(*s)) - *s = toupper(*s); - s++; + int skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; + else + { + if (islower(*s)) + *s = toupper(*s); + s++; + } } } } @@ -1154,25 +1198,13 @@ BOOL strisnormal(char *s) ****************************************************************************/ void string_replace(char *s,char oldc,char newc) { + int skip; while (*s) { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (oldc == *s) - *s = newc; - s++; - } - } + skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; else -#endif /* KANJI_WIN95_COMPATIBILITY */ { if (oldc == *s) *s = newc; @@ -1192,8 +1224,8 @@ void unix_format(char *fname) if (*fname == '/') { pstrcpy(namecopy,fname); - strcpy(fname,"."); - strcat(fname,namecopy); + pstrcpy(fname,"."); + pstrcat(fname,namecopy); } } @@ -1205,44 +1237,50 @@ void dos_format(char *fname) string_replace(fname,'/','\\'); } - /******************************************************************* show a smb message structure ********************************************************************/ void show_msg(char *buf) { - int i; - int bcc=0; - - if (DEBUGLEVEL < 5) return; + int i; + int bcc=0; + + if (DEBUGLEVEL < 5) return; + + DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", + smb_len(buf), + (int)CVAL(buf,smb_com), + (int)CVAL(buf,smb_rcls), + (int)CVAL(buf,smb_reh), + (int)SVAL(buf,smb_err), + (int)CVAL(buf,smb_flg), + (int)SVAL(buf,smb_flg2))); + DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", + (int)SVAL(buf,smb_tid), + (int)SVAL(buf,smb_pid), + (int)SVAL(buf,smb_uid), + (int)SVAL(buf,smb_mid), + (int)CVAL(buf,smb_wct))); + + for (i=0;i<(int)CVAL(buf,smb_wct);i++) + { + DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, + SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); + } - DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n", - smb_len(buf), - (int)CVAL(buf,smb_com), - (int)CVAL(buf,smb_rcls), - (int)CVAL(buf,smb_reh), - (int)SVAL(buf,smb_err), - (int)CVAL(buf,smb_flg), - (int)SVAL(buf,smb_flg2))); - DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n", - (int)SVAL(buf,smb_tid), - (int)SVAL(buf,smb_pid), - (int)SVAL(buf,smb_uid), - (int)SVAL(buf,smb_mid), - (int)CVAL(buf,smb_wct))); + bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); - for (i=0;i<(int)CVAL(buf,smb_wct);i++) - DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i, - SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i))); + DEBUG(5,("smb_bcc=%d\n",bcc)); - bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct))); - DEBUG(5,("smb_bcc=%d\n",bcc)); + if (DEBUGLEVEL < 10) return; - if (DEBUGLEVEL < 10) return; + if (DEBUGLEVEL < 50) + { + bcc = MIN(bcc, 512); + } - dump_data(10, smb_buf(buf), MIN(bcc, 512)); + dump_data(10, smb_buf(buf), bcc); } - /******************************************************************* return the length of an smb packet ********************************************************************/ @@ -1389,7 +1427,7 @@ void dos_clean_name(char *s) *p = 0; else *s = 0; - strcat(s,s1); + pstrcat(s,s1); } trim_string(s,NULL,"\\.."); @@ -1413,7 +1451,7 @@ void unix_clean_name(char *s) if(strncmp(s, "./", 2) == 0) { trim_string(s, "./", NULL); if(*s == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); } while ((p = strstr(s,"/../")) != NULL) @@ -1427,7 +1465,7 @@ void unix_clean_name(char *s) *p = 0; else *s = 0; - strcat(s,s1); + pstrcat(s,s1); } trim_string(s,NULL,"/.."); @@ -1520,7 +1558,7 @@ char *GetWd(char *str) st.st_dev == st2.st_dev && (st2.st_mode & S_IFMT) == S_IFDIR) { - strcpy (str, ino_list[i].text); + pstrcpy (str, ino_list[i].text); /* promote it for future use */ array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i); @@ -1547,7 +1585,7 @@ char *GetWd(char *str) return (NULL); } - strcpy(str,s); + pstrcpy(str,s); DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev)); @@ -1598,7 +1636,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) } if (strlen(s) == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); return(True); } @@ -1659,8 +1697,8 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) if (p && (p != base_name)) { - strcat(newname,"/"); - strcat(newname,p+1); + pstrcat(newname,"/"); + pstrcat(newname,p+1); } { @@ -1689,7 +1727,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) ChDir(wd); if (strlen(s) == 0) - strcpy(s,"./"); + pstrcpy(s,"./"); DEBUG(3,("reduced to %s\n",s)); return(True); @@ -1744,7 +1782,7 @@ void expand_mask(char *Mask,BOOL doext) } else { - strcpy(mext,""); + pstrcpy(mext,""); if (strlen(mbeg) > 8) { pstrcpy(mext,mbeg + 8); @@ -1753,12 +1791,12 @@ void expand_mask(char *Mask,BOOL doext) } if (*mbeg == 0) - strcpy(mbeg,"????????"); + pstrcpy(mbeg,"????????"); if ((*mext == 0) && doext && !hasdot) - strcpy(mext,"???"); + pstrcpy(mext,"???"); if (strequal(mbeg,"*") && *mext==0) - strcpy(mext,"*"); + pstrcpy(mext,"*"); /* expand *'s */ expand_one(mbeg,8); @@ -1766,10 +1804,10 @@ void expand_mask(char *Mask,BOOL doext) expand_one(mext,3); pstrcpy(Mask,dirpart); - if (*dirpart || absolute) strcat(Mask,"\\"); - strcat(Mask,mbeg); - strcat(Mask,"."); - strcat(Mask,mext); + if (*dirpart || absolute) pstrcat(Mask,"\\"); + pstrcat(Mask,mbeg); + pstrcat(Mask,"."); + pstrcat(Mask,mext); DEBUG(6,("Mask expanded to [%s]\n",Mask)); } @@ -1783,6 +1821,15 @@ BOOL strhasupper(char *s) while (*s) { #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1800,9 +1847,14 @@ BOOL strhasupper(char *s) else #endif /* KANJI_WIN95_COMPATIBILITY */ { - if (isupper(*s)) - return(True); - s++; + int skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; + else { + if (isupper(*s)) + return(True); + s++; + } } } return(False); @@ -1816,6 +1868,15 @@ BOOL strhaslower(char *s) while (*s) { #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1841,9 +1902,14 @@ BOOL strhaslower(char *s) else #endif /* KANJI_WIN95_COMPATIBILITY */ { - if (islower(*s)) - return(True); - s++; + int skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; + else { + if (islower(*s)) + return(True); + s++; + } } } return(False); @@ -1857,6 +1923,15 @@ int count_chars(char *s,char c) int count=0; #if !defined(KANJI_WIN95_COMPATIBILITY) + /* + * For completeness we should put in equivalent code for code pages + * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but + * doubt anyone wants Samba to behave differently from Win95 and WinNT + * here. They both treat full width ascii characters as case senstive + * filenames (ie. they don't do the work we do here). + * JRA. + */ + if(lp_client_code_page() == KANJI_CODEPAGE) { /* Win95 treats full width ascii characters as case sensitive. */ @@ -1877,9 +1952,14 @@ int count_chars(char *s,char c) { while (*s) { - if (*s == c) - count++; - s++; + int skip = skip_multibyte_char( *s ); + if( skip != 0 ) + s += skip; + else { + if (*s == c) + count++; + s++; + } } } return(count); @@ -2002,20 +2082,20 @@ read from a socket int read_udp_socket(int fd,char *buf,int len) { int ret; - struct sockaddr sock; + struct sockaddr_in sock; int socklen; socklen = sizeof(sock); bzero((char *)&sock,socklen); bzero((char *)&lastip,sizeof(lastip)); - ret = recvfrom(fd,buf,len,0,&sock,&socklen); + ret = recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen); if (ret <= 0) { DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); return(0); } - lastip = *(struct in_addr *) &sock.sa_data[2]; - lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port); + lastip = sock.sin_addr; + lastport = ntohs(sock.sin_port); DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %d\n", inet_ntoa(lastip), lastport, ret)); @@ -2046,7 +2126,16 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out) if (mincnt == 0) mincnt = maxcnt; while (nread < mincnt) { +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ readret = read(fd, buf + nread, maxcnt - nread); +#endif /* WITH_SSL */ + if (readret == 0) { smb_read_error = READ_EOF; return -1; @@ -2091,7 +2180,16 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out) return -1; } - readret = read(fd, buf+nread, maxcnt-nread); +#ifdef WITH_SSL + if(fd == sslFd){ + readret = SSL_read(ssl, buf + nread, maxcnt - nread); + }else{ + readret = read(fd, buf + nread, maxcnt - nread); + } +#else /* WITH_SSL */ + readret = read(fd, buf+nread, maxcnt-nread); +#endif /* WITH_SSL */ + if (readret == 0) { /* we got EOF on the file descriptor */ smb_read_error = READ_EOF; @@ -2174,18 +2272,29 @@ int read_data(int fd,char *buffer,int N) smb_read_error = 0; while (total < N) - { + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_read(ssl, buffer + total, N - total); + }else{ ret = read(fd,buffer + total,N - total); - if (ret == 0) { - smb_read_error = READ_EOF; - return 0; - } - if (ret == -1) { - smb_read_error = READ_ERROR; - return -1; - } - total += ret; } +#else /* WITH_SSL */ + ret = read(fd,buffer + total,N - total); +#endif /* WITH_SSL */ + + if (ret == 0) + { + smb_read_error = READ_EOF; + return 0; + } + if (ret == -1) + { + smb_read_error = READ_ERROR; + return -1; + } + total += ret; + } return total; } @@ -2199,14 +2308,22 @@ int write_data(int fd,char *buffer,int N) int ret; while (total < N) - { + { +#ifdef WITH_SSL + if(fd == sslFd){ + ret = SSL_write(ssl,buffer + total,N - total); + }else{ ret = write(fd,buffer + total,N - total); + } +#else /* WITH_SSL */ + ret = write(fd,buffer + total,N - total); +#endif /* WITH_SSL */ - if (ret == -1) return -1; - if (ret == 0) return total; + if (ret == -1) return -1; + if (ret == 0) return total; - total += ret; - } + total += ret; + } return total; } @@ -2420,6 +2537,8 @@ BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout) int fromlen = sizeof(from); int32 msg_len = 0; + smb_read_error = 0; + if(timeout != 0) { struct timeval to; @@ -2571,6 +2690,8 @@ BOOL receive_message_or_smb(int smbfd, int oplock_fd, int selrtn; struct timeval to; + smb_read_error = 0; + *got_smb = False; /* @@ -2680,7 +2801,7 @@ int name_extract(char *buf,int ofs,char *name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); - strcpy(name,""); + pstrcpy(name,""); if (d < -50 || d > 50) return(0); return(name_interpret(p,name)); } @@ -2824,7 +2945,7 @@ BOOL string_init(char **dest,char *src) return False; } - strcpy(*dest,src); + pstrcpy(*dest,src); } return(True); } @@ -2886,12 +3007,12 @@ BOOL string_sub(char *s,char *pattern,char *insert) return(ret); } - - /********************************************************* * Recursive routine that is called by mask_match. -* Does the actual matching. +* Does the actual matching. Returns True if matched, +* False if failed. *********************************************************/ + BOOL do_match(char *str, char *regexp, int case_sig) { char *p; @@ -2904,48 +3025,61 @@ BOOL do_match(char *str, char *regexp, int case_sig) case '*': /* Look for a character matching - the one after the '*' */ + the one after the '*' */ p++; if(!*p) - return True; /* Automatic match */ + return True; /* Automatic match */ while(*str) { - while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str)))) - str++; - if(do_match(str,p,case_sig)) - return True; - if(!*str) - return False; - else - str++; + while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str)))) + str++; + /* Now eat all characters that match, as + we want the *last* character to match. */ + while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str)))) + str++; + str--; /* We've eaten the match char after the '*' */ + if(do_match(str,p,case_sig)) { + return True; + } + if(!*str) { + return False; + } else { + str++; + } } return False; default: if(case_sig) { - if(*str != *p) - return False; + if(*str != *p) { + return False; + } } else { - if(toupper(*str) != toupper(*p)) - return False; + if(toupper(*str) != toupper(*p)) { + return False; + } } str++, p++; break; } } + if(!*p && !*str) return True; - if (!*p && str[0] == '.' && str[1] == 0) + if (!*p && str[0] == '.' && str[1] == 0) { return(True); + } - if (!*str && *p == '?') - { - while (*p == '?') p++; - return(!*p); - } + if (!*str && *p == '?') { + while (*p == '?') + p++; + return(!*p); + } - if(!*str && (*p == '*' && p[1] == '\0')) + if(!*str && (*p == '*' && p[1] == '\0')) { return True; + } + return False; } @@ -2954,106 +3088,239 @@ BOOL do_match(char *str, char *regexp, int case_sig) * Routine to match a given string with a regexp - uses * simplified regexp that takes * and ? only. Case can be * significant or not. +* The 8.3 handling was rewritten by Ums Harald *********************************************************/ + BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) { char *p; - pstring p1, p2; + pstring t_pattern, t_filename, te_pattern, te_filename; fstring ebase,eext,sbase,sext; - BOOL matched; + BOOL matched = False; /* Make local copies of str and regexp */ - StrnCpy(p1,regexp,sizeof(pstring)-1); - StrnCpy(p2,str,sizeof(pstring)-1); - - if (!strchr(p2,'.')) { - strcat(p2,"."); - } + pstrcpy(t_pattern,regexp); + pstrcpy(t_filename,str); -/* - if (!strchr(p1,'.')) { - strcat(p1,"."); - } -*/ +#if 0 + /* + * Not sure if this is a good idea. JRA. + */ + if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False)) + trans2 = False; +#endif #if 0 - if (strchr(p1,'.')) - { - string_sub(p1,"*.*","*"); - string_sub(p1,".*","*"); - } + if (!strchr(t_filename,'.')) { + pstrcat(t_filename,"."); + } #endif /* Remove any *? and ** as they are meaningless */ - for(p = p1; *p; p++) - while( *p == '*' && (p[1] == '?' ||p[1] == '*')) - (void)strcpy( &p[1], &p[2]); + string_sub(t_pattern, "*?", "*"); + string_sub(t_pattern, "**", "*"); - if (strequal(p1,"*")) return(True); - - DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); + if (strequal(t_pattern,"*")) + return(True); - if (trans2) { - fstrcpy(ebase,p1); - fstrcpy(sbase,p2); + DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig)); + + if(trans2) { + /* + * Match each component of the regexp, split up by '.' + * characters. + */ + char *fp, *rp, *cp2, *cp1; + BOOL last_wcard_was_star = False; + int num_path_components, num_regexp_components; + + pstrcpy(te_pattern,t_pattern); + pstrcpy(te_filename,t_filename); + /* + * Remove multiple "*." patterns. + */ + string_sub(te_pattern, "*.*.", "*."); + num_regexp_components = count_chars(te_pattern, '.'); + num_path_components = count_chars(te_filename, '.'); + + /* + * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z + */ + if(num_regexp_components == 0) + matched = do_match( te_filename, te_pattern, case_sig); + else { + for( cp1 = te_pattern, cp2 = te_filename; cp1;) { + fp = strchr(cp2, '.'); + if(fp) + *fp = '\0'; + rp = strchr(cp1, '.'); + if(rp) + *rp = '\0'; + + if(cp1[strlen(cp1)-1] == '*') + last_wcard_was_star = True; + else + last_wcard_was_star = False; + + if(!do_match(cp2, cp1, case_sig)) + break; + + cp1 = rp ? rp + 1 : NULL; + cp2 = fp ? fp + 1 : ""; + + if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) { + /* Eat the extra path components. */ + int i; + + for(i = 0; i < num_path_components - num_regexp_components; i++) { + fp = strchr(cp2, '.'); + if(fp) + *fp = '\0'; + + if((cp1 != NULL) && do_match( cp2, cp1, case_sig)) { + cp2 = fp ? fp + 1 : ""; + break; + } + cp2 = fp ? fp + 1 : ""; + } + num_path_components -= i; + } + } + if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star)) + matched = True; + } } else { - if ((p=strrchr(p1,'.'))) { - *p = 0; - fstrcpy(ebase,p1); - fstrcpy(eext,p+1); + + /* ------------------------------------------------- + * Behaviour of Win95 + * for 8.3 filenames and 8.3 Wildcards + * ------------------------------------------------- + */ + if (strequal (t_filename, ".")) { + /* + * Patterns: *.* *. ?. ? are valid + * + */ + if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") || + strequal(t_pattern, "?.") || strequal(t_pattern, "?")) + matched = True; + } else if (strequal (t_filename, "..")) { + /* + * Patterns: *.* *. ?. ? *.? are valid + * + */ + if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") || + strequal(t_pattern, "?.") || strequal(t_pattern, "?") || + strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*")) + matched = True; } else { - fstrcpy(ebase,p1); - eext[0] = 0; - } - if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) { - *p = 0; - fstrcpy(sbase,p2); - fstrcpy(sext,p+1); - } else { - fstrcpy(sbase,p2); - fstrcpy(sext,""); - } - } + if ((p = strrchr (t_pattern, '.'))) { + /* + * Wildcard has a suffix. + */ + *p = 0; + fstrcpy (ebase, t_pattern); + if (p[1]) { + fstrcpy (eext, p + 1); + } else { + /* pattern ends in DOT: treat as if there is no DOT */ + *eext = 0; + if (strequal (ebase, "*")) + return (True); + } + } else { + /* + * No suffix for wildcard. + */ + fstrcpy (ebase, t_pattern); + eext[0] = 0; + } - matched = do_match(sbase,ebase,case_sig) && - (trans2 || do_match(sext,eext,case_sig)); + p = strrchr (t_filename, '.'); + if (p && (p[1] == 0) ) { + /* + * Filename has an extension of '.' only. + */ + *p = 0; /* nuke dot at end of string */ + p = 0; /* and treat it as if there is no extension */ + } + + if (p) { + /* + * Filename has an extension. + */ + *p = 0; + fstrcpy (sbase, t_filename); + fstrcpy (sext, p + 1); + if (*eext) { + matched = do_match(sbase, ebase, case_sig) + && do_match(sext, eext, case_sig); + } else { + /* pattern has no extension */ + /* Really: match complete filename with pattern ??? means exactly 3 chars */ + matched = do_match(str, ebase, case_sig); + } + } else { + /* + * Filename has no extension. + */ + fstrcpy (sbase, t_filename); + fstrcpy (sext, ""); + if (*eext) { + /* pattern has extension */ + matched = do_match(sbase, ebase, case_sig) + && do_match(sext, eext, case_sig); + } else { + matched = do_match(sbase, ebase, case_sig); +#ifdef EMULATE_WEIRD_W95_MATCHING + /* + * Even Microsoft has some problems + * Behaviour Win95 -> local disk + * is different from Win95 -> smb drive from Nt 4.0 + * This branch would reflect the Win95 local disk behaviour + */ + if (!matched) { + /* a? matches aa and a in w95 */ + fstrcat (sbase, "."); + matched = do_match(sbase, ebase, case_sig); + } +#endif + } + } + } + } DEBUG(8,("mask_match returning %d\n", matched)); return matched; } - - /**************************************************************************** become a daemon, discarding the controlling terminal ****************************************************************************/ void become_daemon(void) { -#ifndef NO_FORK_DEBUG - if (fork()) - exit(0); + if (fork()) { + _exit(0); + } /* detach from the terminal */ -#ifdef USE_SETSID - setsid(); -#else /* USE_SETSID */ -#ifdef TIOCNOTTY - { - int i = open("/dev/tty", O_RDWR); - if (i >= 0) - { - ioctl(i, (int) TIOCNOTTY, (char *)0); - close(i); - } - } -#endif /* TIOCNOTTY */ -#endif /* USE_SETSID */ - /* Close fd's 0,1,2. Needed if started by rsh */ - close_low_fds(); -#endif /* NO_FORK_DEBUG */ +#ifdef HAVE_SETSID + setsid(); +#elif defined(TIOCNOTTY) + { + int i = open("/dev/tty", O_RDWR); + if (i != -1) { + ioctl(i, (int) TIOCNOTTY, (char *)0); + close(i); + } + } +#endif /* HAVE_SETSID */ + + /* Close fd's 0,1,2. Needed if started by rsh */ + close_low_fds(); } @@ -3152,7 +3419,7 @@ int set_filelen(int fd, long len) extend a file with ftruncate. Provide alternate implementation for this */ -#if FTRUNCATE_CAN_EXTEND +#ifdef HAVE_FTRUNCATE_EXTEND return ftruncate(fd, len); #else struct stat st; @@ -3221,11 +3488,11 @@ char *dirname_dos(char *path,char *buf) char *p = strrchr(path,'\\'); if (!p) - strcpy(buf,path); + pstrcpy(buf,path); else { *p = 0; - strcpy(buf,path); + pstrcpy(buf,path); *p = '\\'; } @@ -3241,9 +3508,9 @@ static char *filename_dos(char *path,char *buf) char *p = strrchr(path,'\\'); if (!p) - strcpy(buf,path); + pstrcpy(buf,path); else - strcpy(buf,p+1); + pstrcpy(buf,p+1); return(buf); } @@ -3274,21 +3541,6 @@ void *Realloc(void *p,int size) return(ret); } -#ifdef NOSTRDUP -/**************************************************************************** -duplicate a string -****************************************************************************/ - char *strdup(char *s) -{ - char *ret = NULL; - if (!s) return(NULL); - ret = (char *)malloc(strlen(s)+1); - if (!ret) return(NULL); - strcpy(ret,s); - return(ret); -} -#endif - /**************************************************************************** Signal handler for SIGPIPE (write on a disconnected socket) @@ -3319,7 +3571,7 @@ BOOL get_myname(char *my_name,struct in_addr *ip) /* get host info */ if ((hp = Get_Hostbyname(hostname)) == 0) { - DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname)); + DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",hostname)); return False; } @@ -3368,13 +3620,14 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr) /* get host info */ if ((hp = Get_Hostbyname(host_name)) == 0) { - DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name)); + DEBUG(0,( "Get_Hostbyname: Unknown host %s\n",host_name)); return -1; } bzero((char *)&sock,sizeof(sock)); memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length); -#if defined(__FreeBSD__) || defined(NETBSD) || defined(__OpenBSD__) /* XXX not the right ifdef */ + +#ifdef HAVE_SOCK_SIN_LEN sock.sin_len = sizeof(sock); #endif sock.sin_port = htons( port ); @@ -3469,6 +3722,7 @@ connect_again: if (ret < 0) { DEBUG(1,("error connecting to %s:%d (%s)\n", inet_ntoa(*addr),port,strerror(errno))); + close(res); return -1; } @@ -3548,7 +3802,7 @@ uint32 interpret_addr(char *str) return 0; } if(hp->h_addr == NULL) { - DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str)); + DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str)); return 0; } putip((char *)&res,(char *)hp->h_addr); @@ -3635,82 +3889,124 @@ static BOOL matchname(char *remotehost,struct in_addr addr) static BOOL global_client_name_done = False; static BOOL global_client_addr_done = False; -void reset_globals_after_fork() +void reset_globals_after_fork(void) { global_client_name_done = False; global_client_addr_done = False; + + /* + * Re-seed the random crypto generator, so all smbd's + * started from the same parent won't generate the same + * sequence. + */ + { + unsigned char dummy; + generate_random_buffer( &dummy, 1, True); + } } /******************************************************************* return the DNS name of the client ******************************************************************/ -char *client_name(void) -{ - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static pstring name_buf; - struct hostent *hp; - - if (global_client_name_done) - return name_buf; - - strcpy(name_buf,"UNKNOWN"); - - if (Client == -1) { - return name_buf; - } - - if (getpeername(Client, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); - return name_buf; - } - - /* Look up the remote host name. */ - if ((hp = gethostbyaddr((char *) &sockin->sin_addr, - sizeof(sockin->sin_addr), - AF_INET)) == 0) { - DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr())); - StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1); - } else { - StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); - if (!matchname(name_buf, sockin->sin_addr)) { - DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr())); - strcpy(name_buf,"UNKNOWN"); - } - } - global_client_name_done = True; - return name_buf; +char *client_name(int fd) +{ + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static pstring name_buf; + struct hostent *hp; + static int last_fd=-1; + + if (global_client_name_done && last_fd == fd) + return name_buf; + + last_fd = fd; + global_client_name_done = False; + + pstrcpy(name_buf,"UNKNOWN"); + + if (fd == -1) { + return name_buf; + } + + if (getpeername(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed\n")); + return name_buf; + } + + /* Look up the remote host name. */ + if ((hp = gethostbyaddr((char *) &sockin->sin_addr, + sizeof(sockin->sin_addr), + AF_INET)) == 0) { + DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd))); + StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1); + } else { + StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1); + if (!matchname(name_buf, sockin->sin_addr)) { + DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd))); + pstrcpy(name_buf,"UNKNOWN"); + } + } + global_client_name_done = True; + return name_buf; } /******************************************************************* return the IP addr of the client as a string ******************************************************************/ -char *client_addr(void) +char *client_addr(int fd) { - struct sockaddr sa; - struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); - int length = sizeof(sa); - static fstring addr_buf; + struct sockaddr sa; + struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa); + int length = sizeof(sa); + static fstring addr_buf; + static int last_fd = -1; - if (global_client_addr_done) - return addr_buf; + if (global_client_addr_done && fd == last_fd) + return addr_buf; - strcpy(addr_buf,"0.0.0.0"); + last_fd = fd; + global_client_addr_done = False; - if (Client == -1) { - return addr_buf; - } + fstrcpy(addr_buf,"0.0.0.0"); - if (getpeername(Client, &sa, &length) < 0) { - DEBUG(0,("getpeername failed\n")); - return addr_buf; - } + if (fd == -1) { + return addr_buf; + } + + if (getpeername(fd, &sa, &length) < 0) { + DEBUG(0,("getpeername failed\n")); + return addr_buf; + } + + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + + global_client_addr_done = True; + return addr_buf; +} - fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); +#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) +/****************************************************************** + Remove any mount options such as -rsize=2048,wsize=2048 etc. + Based on a fix from . +*******************************************************************/ + +static void strip_mount_options( pstring *str) +{ + if (**str == '-') + { + char *p = *str; + while(*p && !isspace(*p)) + p++; + while(*p && isspace(*p)) + p++; + if(*p) { + pstring tmp_str; - global_client_addr_done = True; - return addr_buf; + pstrcpy(tmp_str, p); + pstrcpy(*str, tmp_str); + } + } } /******************************************************************* @@ -3720,7 +4016,61 @@ char *client_addr(void) As we may end up doing both, cache the last YP result. *******************************************************************/ -#if (defined(NETGROUP) && defined(AUTOMOUNT)) +#ifdef NISPLUS_HOME +static char *automount_lookup(char *user_name) +{ + static fstring last_key = ""; + static pstring last_value = ""; + + char *nis_map = (char *)lp_nis_home_map_name(); + + char nis_domain[NIS_MAXNAMELEN + 1]; + char buffer[NIS_MAXATTRVAL + 1]; + nis_result *result; + nis_object *object; + entry_obj *entry; + + strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN); + nis_domain[NIS_MAXNAMELEN] = '\0'; + + DEBUG(5, ("NIS+ Domain: %s\n", nis_domain)); + + if (strcmp(user_name, last_key)) + { + slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain); + DEBUG(5, ("NIS+ querystring: %s\n", buffer)); + + if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL)) + { + if (result->status != NIS_SUCCESS) + { + DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status))); + fstrcpy(last_key, ""); pstrcpy(last_value, ""); + } + else + { + object = result->objects.objects_val; + if (object->zo_data.zo_type == ENTRY_OBJ) + { + entry = &object->zo_data.objdata_u.en_data; + DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type)); + DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val)); + + pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val); + string_sub(last_value, "&", user_name); + fstrcpy(last_key, user_name); + } + } + } + nis_freeresult(result); + } + + strip_mount_options(&last_value); + + DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value)); + return last_value; +} +#else /* NISPLUS_HOME */ static char *automount_lookup(char *user_name) { static fstring last_key = ""; @@ -3764,9 +4114,12 @@ static char *automount_lookup(char *user_name) last_value[nis_result_len] = '\0'; } + strip_mount_options(&last_value); + DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value)); return last_value; } +#endif /* NISPLUS_HOME */ #endif /******************************************************************* @@ -3779,14 +4132,15 @@ char *automount_server(char *user_name) { static pstring server_name; -#if (defined(NETGROUP) && defined (AUTOMOUNT)) - int home_server_len; - - /* set to default of local machine */ + /* use the local machine name as the default */ + /* this will be the default if WITH_AUTOMOUNT is not used or fails */ pstrcpy(server_name, local_machine); +#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) + if (lp_nis_home_map()) { + int home_server_len; char *automount_value = automount_lookup(user_name); home_server_len = strcspn(automount_value,":"); DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len)); @@ -3797,9 +4151,6 @@ char *automount_server(char *user_name) strncpy(server_name, automount_value, home_server_len); server_name[home_server_len] = '\0'; } -#else - /* use the local machine name instead of the auto-map server */ - pstrcpy(server_name, local_machine); #endif DEBUG(4,("Home server: %s\n", server_name)); @@ -3816,27 +4167,25 @@ char *automount_path(char *user_name) { static pstring server_path; -#if (defined(NETGROUP) && defined (AUTOMOUNT)) - char *home_path_start; + /* use the passwd entry as the default */ + /* this will be the default if WITH_AUTOMOUNT is not used or fails */ + /* pstrcpy() copes with get_home_dir() returning NULL */ + pstrcpy(server_path, get_home_dir(user_name)); - /* set to default of no string */ - server_path[0] = 0; +#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) if (lp_nis_home_map()) { + char *home_path_start; char *automount_value = automount_lookup(user_name); home_path_start = strchr(automount_value,':'); if (home_path_start != NULL) { DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n", home_path_start?(home_path_start+1):"")); - strcpy(server_path, home_path_start+1); + pstrcpy(server_path, home_path_start+1); } } -#else - /* use the passwd entry instead of the auto-map server entry */ - /* pstrcpy() copes with get_home_dir() returning NULL */ - pstrcpy(server_path, get_home_dir(user_name)); #endif DEBUG(4,("Home server path: %s\n", server_path)); @@ -3863,7 +4212,7 @@ void standard_sub_basic(char *str) { case 'G' : { - if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL) + if ((pass = Get_Pwnam(username,False))!=NULL) { string_sub(p,"%G",gidtoname(pass->pw_gid)); } @@ -3874,54 +4223,62 @@ void standard_sub_basic(char *str) break; } case 'N' : string_sub(p,"%N", automount_server(username)); break; - case 'I' : string_sub(p,"%I", client_addr()); break; + case 'I' : string_sub(p,"%I", client_addr(Client)); break; case 'L' : string_sub(p,"%L", local_machine); break; - case 'M' : string_sub(p,"%M", client_name()); break; + case 'M' : string_sub(p,"%M", client_name(Client)); break; case 'R' : string_sub(p,"%R", remote_proto); break; case 'T' : string_sub(p,"%T", timestring()); break; case 'U' : string_sub(p,"%U", username); break; case 'a' : string_sub(p,"%a", remote_arch); break; case 'd' : { - sprintf(pidstr,"%d",(int)getpid()); + slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid()); string_sub(p,"%d", pidstr); break; } case 'h' : string_sub(p,"%h", myhostname); break; case 'm' : string_sub(p,"%m", remote_machine); break; case 'v' : string_sub(p,"%v", VERSION); break; - case '$' : /* Expand environment variables */ - { - /* Contributed by Branko Cibej */ - fstring envname; - char *envval; - char *q, *r; - int copylen; - - if (*(p+2) != '(') { p+=2; break; } - if ((q = strchr(p,')')) == NULL) - { - DEBUG(0,("standard_sub_basic: Unterminated environment \ -variable [%s]\n", p)); - p+=2; break; - } - - r = p+3; - copylen = MIN((q-r),(sizeof(envname)-1)); - strncpy(envname,r,copylen); - envname[copylen] = '\0'; - if ((envval = getenv(envname)) == NULL) - { - DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n", - envname)); - p+=2; break; - } - copylen = MIN((q+1-p),(sizeof(envname)-1)); - strncpy(envname,p,copylen); - envname[copylen] = '\0'; - string_sub(p,envname,envval); - break; - } + case '$' : /* Expand environment variables */ + { + /* Contributed by Branko Cibej */ + fstring envname; + char *envval; + char *q, *r; + int copylen; + + if (*(p+2) != '(') + { + p+=2; + break; + } + if ((q = strchr(p,')')) == NULL) + { + DEBUG(0,("standard_sub_basic: Unterminated environment \ + variable [%s]\n", p)); + p+=2; + break; + } + + r = p+3; + copylen = MIN((q-r),(sizeof(envname)-1)); + strncpy(envname,r,copylen); + envname[copylen] = '\0'; + + if ((envval = getenv(envname)) == NULL) + { + DEBUG(0,("standard_sub_basic: Environment variable [%s] not set\n", + envname)); + p+=2; + break; + } + + copylen = MIN((q+1-p),(sizeof(envname)-1)); + strncpy(envname,p,copylen); + envname[copylen] = '\0'; + string_sub(p,envname,envval); + break; + } case '\0': p++; break; /* don't run off end if last character is % */ default : p+=2; break; } @@ -3975,11 +4332,20 @@ struct hostent *Get_Hostbyname(char *name) exit(0); } + + /* + * This next test is redundent and causes some systems (with + * broken isalnum() calls) problems. + * JRA. + */ + +#if 0 if (!isalnum(*name2)) { free(name2); return(NULL); } +#endif /* 0 */ ret = sys_gethostbyname(name2); if (ret != NULL) @@ -4029,7 +4395,7 @@ char *uidtoname(int uid) static char name[40]; struct passwd *pass = getpwuid(uid); if (pass) return(pass->pw_name); - sprintf(name,"%d",uid); + slprintf(name, sizeof(name) - 1, "%d",uid); return(name); } @@ -4038,31 +4404,11 @@ turn a gid into a group name ********************************************************************/ char *gidtoname(int gid) { - static char name[40]; - struct group *grp = getgrgid(gid); - if (grp) return(grp->gr_name); - sprintf(name,"%d",gid); - return(name); -} - -/******************************************************************* -block sigs -********************************************************************/ -void BlockSignals(BOOL block,int signum) -{ -#ifdef USE_SIGBLOCK - int block_mask = sigmask(signum); - static int oldmask = 0; - if (block) - oldmask = sigblock(block_mask); - else - sigsetmask(oldmask); -#elif defined(USE_SIGPROCMASK) - sigset_t set; - sigemptyset(&set); - sigaddset(&set,signum); - sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); -#endif + static char name[40]; + struct group *grp = getgrgid(gid); + if (grp) return(grp->gr_name); + slprintf(name,sizeof(name) - 1, "%d",gid); + return(name); } #if AJT @@ -4071,15 +4417,10 @@ my own panic function - not suitable for general use ********************************************************************/ void ajt_panic(void) { - system("/usr/bin/X11/xedit -display solen:0 /tmp/ERROR_FAULT"); + system("/usr/bin/X11/xedit -display :0 /tmp/ERROR_FAULT"); } #endif -#ifdef USE_DIRECT -#define DIRECT direct -#else -#define DIRECT dirent -#endif /******************************************************************* a readdir wrapper which just returns the file name @@ -4087,43 +4428,33 @@ also return the inode number if requested ********************************************************************/ char *readdirname(void *p) { - struct DIRECT *ptr; - char *dname; + struct dirent *ptr; + char *dname; - if (!p) return(NULL); + if (!p) return(NULL); - ptr = (struct DIRECT *)readdir(p); - if (!ptr) return(NULL); + ptr = (struct dirent *)readdir(p); + if (!ptr) return(NULL); - dname = ptr->d_name; + dname = ptr->d_name; #ifdef NEXT2 - if (telldir(p) < 0) return(NULL); + if (telldir(p) < 0) return(NULL); #endif -#ifdef SUNOS5 - /* this handles a broken compiler setup, causing a mixture - of BSD and SYSV headers and libraries */ - { - static BOOL broken_readdir = False; - if (!broken_readdir && !(*(dname)) && strequal("..",dname-2)) - { - DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n")); - broken_readdir = True; - } - if (broken_readdir) - dname = dname - 2; - } +#ifdef HAVE_BROKEN_READDIR + /* using /usr/ucb/cc is BAD */ + dname = dname - 2; #endif - { - static pstring buf; - pstrcpy(buf, dname); - unix_to_dos(buf, True); - dname = buf; - } + { + static pstring buf; + memcpy(buf, dname, NAMLEN(ptr)+1); + unix_to_dos(buf, True); + dname = buf; + } - return(dname); + return(dname); } /******************************************************************* @@ -4147,7 +4478,7 @@ BOOL is_in_path(char *name, name_compare_entry *namelist) /* Get the last component of the unix name. */ p = strrchr(name, '/'); - strncpy(last_component, p ? p : name, sizeof(last_component)-1); + strncpy(last_component, p ? ++p : name, sizeof(last_component)-1); last_component[sizeof(last_component)-1] = '\0'; for(; namelist->name != NULL; namelist++) @@ -4445,23 +4776,23 @@ void set_remote_arch(enum remote_arch_types type) switch( type ) { case RA_WFWG: - strcpy(remote_arch, "WfWg"); + fstrcpy(remote_arch, "WfWg"); return; case RA_OS2: - strcpy(remote_arch, "OS2"); + fstrcpy(remote_arch, "OS2"); return; case RA_WIN95: - strcpy(remote_arch, "Win95"); + fstrcpy(remote_arch, "Win95"); return; case RA_WINNT: - strcpy(remote_arch, "WinNT"); + fstrcpy(remote_arch, "WinNT"); return; case RA_SAMBA: - strcpy(remote_arch,"Samba"); + fstrcpy(remote_arch,"Samba"); return; default: ra_type = RA_UNKNOWN; - strcpy(remote_arch, "UNKNOWN"); + fstrcpy(remote_arch, "UNKNOWN"); break; } } @@ -4469,7 +4800,7 @@ void set_remote_arch(enum remote_arch_types type) /******************************************************************* Get the remote_arch type. ********************************************************************/ -enum remote_arch_types get_remote_arch() +enum remote_arch_types get_remote_arch(void) { return ra_type; } @@ -4638,57 +4969,67 @@ int unistrcpy(char *dst, char *src) return num_wchars; } - /******************************************************************* -safe string copy into a fstring +safe string copy into a known length string. maxlength does not +include the terminating zero. ********************************************************************/ -void fstrcpy(char *dest, char *src) +char *safe_strcpy(char *dest, char *src, int maxlength) { - int maxlength = sizeof(fstring) - 1; + int len; + if (!dest) { - DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); - return; + DEBUG(0,("ERROR: NULL dest in safe_strcpy\n")); + return NULL; } if (!src) { *dest = 0; - return; + return dest; } + + len = strlen(src); + + if (len > maxlength) { + DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n", + len-maxlength, src)); + len = maxlength; + } - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", - strlen(src))); - } -} + memcpy(dest, src, len); + dest[len] = 0; + return dest; +} /******************************************************************* -safe string copy into a pstring +safe string cat into a string. maxlength does not +include the terminating zero. ********************************************************************/ -void pstrcpy(char *dest, char *src) +char *safe_strcat(char *dest, char *src, int maxlength) { - int maxlength = sizeof(pstring) - 1; + int src_len, dest_len; + if (!dest) { - DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); - return; + DEBUG(0,("ERROR: NULL dest in safe_strcat\n")); + return NULL; } - + if (!src) { - *dest = 0; - return; - } - - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", - strlen(src))); - } -} + return dest; + } + src_len = strlen(src); + dest_len = strlen(dest); + + if (src_len + dest_len > maxlength) { + DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n", + src_len + dest_len - maxlength, src)); + src_len = maxlength - dest_len; + } + + memcpy(&dest[dest_len], src, src_len); + dest[dest_len + src_len] = 0; + return dest; +} /******************************************************************* align a pointer to a multiple of 4 bytes @@ -4776,4 +5117,86 @@ char *tab_depth(int depth) return spaces; } +/***************************************************************** + Convert a SID to an ascii string. +*****************************************************************/ + +char *sid_to_string(pstring sidstr_out, DOM_SID *sid) +{ + char subauth[16]; + int i; + /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ + uint32 ia = (sid->id_auth[5]) + + (sid->id_auth[4] << 8 ) + + (sid->id_auth[3] << 16) + + (sid->id_auth[2] << 24); + + slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia); + for (i = 0; i < sid->num_auths; i++) + { + slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]); + pstrcat(sidstr_out, subauth); + } + + DEBUG(7,("sid_to_string returning %s\n", sidstr_out)); + return sidstr_out; +} + +/***************************************************************** + Convert a string to a SID. Returns True on success, False on fail. +*****************************************************************/ + +BOOL string_to_sid(DOM_SID *sidout, char *sidstr) +{ + pstring tok; + char *p = sidstr; + /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */ + uint32 ia; + + memset((char *)sidout, '\0', sizeof(DOM_SID)); + + if(StrnCaseCmp( sidstr, "S-", 2)) { + DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr)); + return False; + } + + p += 2; + if(!next_token(&p, tok, "-")) { + DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr)); + return False; + } + + /* Get the revision number. */ + sidout->sid_rev_num = atoi(tok); + + if(!next_token(&p, tok, "-")) { + DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr)); + return False; + } + + /* identauth in decimal should be < 2^32 */ + ia = atoi(tok); + + /* NOTE - the ia value is in big-endian format. */ + sidout->id_auth[0] = 0; + sidout->id_auth[1] = 0; + sidout->id_auth[2] = (ia & 0xff000000) >> 24; + sidout->id_auth[3] = (ia & 0x00ff0000) >> 16; + sidout->id_auth[4] = (ia & 0x0000ff00) >> 8; + sidout->id_auth[5] = (ia & 0x000000ff); + + sidout->num_auths = 0; + + while(next_token(&p, tok, "-") && sidout->num_auths < MAXSUBAUTHS) { + /* + * NOTE - the subauths are in native machine-endian format. They + * are converted to little-endian when linearized onto the wire. + */ + sidout->sub_auths[sidout->num_auths++] = atoi(tok); + } + + DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr)); + + return True; +}