#include "includes.h"
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
-#ifdef NISPLUS
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
+#ifdef WITH_NISPLUS_HOME
#include <rpcsvc/nis.h>
#else
#include "rpcsvc/ypclnt.h"
#endif
#endif
+#ifdef WITH_SSL
+#include <ssl.h>
+#undef Realloc /* SSLeay defines this and samba has a function of this name */
+extern SSL *ssl;
+extern int sslFd;
+#endif /* WITH_SSL */
+
pstring scope = "";
-int DEBUGLEVEL = 1;
+extern int DEBUGLEVEL;
BOOL passive = False;
/* a default finfo structure to ensure all fields are sensible */
file_info def_finfo = {-1,0,0,0,0,0,0,""};
-/* these are some file handles where debug info will be stored */
-FILE *dbf = NULL;
-
/* the client file descriptor */
int Client = -1;
*/
int case_default = CASE_LOWER;
-pstring debugf = "";
-int syslog_level;
-
/* the following control case operations - they are put here so the
client can link easily */
BOOL case_sensitive;
int smb_read_error = 0;
-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);
-
- DEBUGLEVEL--;
-
- if(DEBUGLEVEL < 0)
- DEBUGLEVEL = 0;
-
- 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
- return(0);
-}
-#endif /* SIGUSR1 */
-
-#if defined(SIGUSR1)
-/**************************************************************************** **
- catch a sigusr1 - increase the debug log level.
- **************************************************************************** */
-int sig_usr1(void)
-{
- BlockSignals( True, SIGUSR1);
-
- DEBUGLEVEL++;
-
- if(DEBUGLEVEL > 10)
- DEBUGLEVEL = 10;
-
- 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
- return(0);
-}
-#endif /* SIGUSR1 */
-
-
-/*******************************************************************
- get ready for syslog stuff
- ******************************************************************/
-void setup_logging(char *pname,BOOL interactive)
-{
-#ifdef SYSLOG
- if (!interactive) {
- char *p = strrchr(pname,'/');
- if (p) pname = p+1;
-#ifdef LOG_DAEMON
- openlog(pname, LOG_PID, SYSLOG_FACILITY);
-#else /* for old systems that have no facility codes. */
- openlog(pname, LOG_PID);
-#endif
- }
-#endif
- if (interactive) {
- stdout_logging = True;
- dbf = stdout;
- }
-}
-
-
-BOOL append_log=False;
-/****************************************************************************
-reopen the log files
-****************************************************************************/
-void reopen_logs(void)
-{
- pstring fname;
-
- if (DEBUGLEVEL > 0)
- {
- strcpy(fname,debugf);
- if (lp_loaded() && (*lp_logfile()))
- strcpy(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);
- }
- }
- else
- {
- if (dbf)
- {
- fclose(dbf);
- dbf = NULL;
- }
- }
-}
-
-
-/*******************************************************************
-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;
-
- maxlog = lp_max_log_size() * 1024;
- if (!dbf || maxlog <= 0) return;
-
- if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
- 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);
- reopen_logs();
- }
- }
- debug_count=0;
-}
-
-
-/*******************************************************************
-write an debug message on the debugfile. This is called by the DEBUG
-macro
-********************************************************************/
-#ifdef __STDC__
- int Debug1(char *format_str, ...)
-{
-#else
- int Debug1(va_alist)
-va_dcl
-{
- char *format_str;
-#endif
- va_list ap;
- int old_errno = errno;
-
- if (stdout_logging) {
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- errno = old_errno;
- return(0);
- }
-
-#ifdef SYSLOG
- if (!lp_syslog_only())
-#endif
- {
- if (!dbf) {
- int oldumask = umask(022);
- if(append_log)
- dbf = fopen(debugf,"a");
- else
- dbf = fopen(debugf,"w");
- umask(oldumask);
- if (dbf) {
- setbuf(dbf,NULL);
- } else {
- errno = old_errno;
- return(0);
- }
- }
- }
-
-#ifdef SYSLOG
- if (syslog_level < lp_syslog())
- {
- /*
- * map debug levels to syslog() priorities
- * note that not all DEBUG(0, ...) calls are
- * necessarily errors
- */
- static int priority_map[] = {
- LOG_ERR, /* 0 */
- LOG_WARNING, /* 1 */
- LOG_NOTICE, /* 2 */
- LOG_INFO, /* 3 */
- };
- int priority;
- pstring msgbuf;
-
- if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
- syslog_level < 0)
- priority = LOG_DEBUG;
- else
- priority = priority_map[syslog_level];
-
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vsprintf(msgbuf, format_str, ap);
- va_end(ap);
-
- msgbuf[255] = '\0';
- syslog(priority, "%s", msgbuf);
- }
-#endif
-
-#ifdef SYSLOG
- if (!lp_syslog_only())
-#endif
- {
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- fflush(dbf);
- }
-
- check_log_size();
-
- errno = old_errno;
-
- return(0);
-}
-
/****************************************************************************
find a suitable temporary directory. The result should be copied immediately
as it may be overwritten by a subsequent call
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<size;i++) idest[i] = isrc[i];
- } else {
- /* simplest */
- char *cdest = (char *)dest;
- char *csrc = (char *)src;
- for (i=0;i<size;i++) cdest[i] = csrc[i];
- }
- }
- else
- {
- /* must backward copy */
- if (d-s >= 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)
****************************************************************************/
void set_socket_options(int fd, char *options)
{
- string tok;
+ fstring tok;
while (next_token(&options,tok," \t,"))
{
****************************************************************************/
void close_sockets(void )
{
+#ifdef WITH_SSL
+ sslutil_disconnect(Client);
+#endif /* WITH_SSL */
+
close(Client);
Client = 0;
}
/****************************************************************************
determine whether we are in the specified group
****************************************************************************/
-BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
+BOOL in_group(gid_t group, int current_gid, int ngroups, GID_T *groups)
{
- int i;
+ int i;
- if (group == current_gid) return(True);
+ if (group == current_gid) return(True);
- for (i=0;i<ngroups;i++)
- if (group == groups[i])
- return(True);
+ for (i=0;i<ngroups;i++)
+ if (group == groups[i])
+ return(True);
- return(False);
+ return(False);
}
/****************************************************************************
{
char *d = dest;
-#if AJT
/* I don't want to get lazy with these ... */
if (!dest || !src) {
- DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
- ajt_panic();
+ DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
+ smb_panic("invalid StrCpy");
}
-#endif
if (!dest) return(NULL);
if (!src) {
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;
********************************************************************/
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);
}
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++;
+ }
}
}
}
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++;
+ }
}
}
}
****************************************************************************/
void string_replace(char *s,char oldc,char newc)
{
+ int skip;
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. */
- 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;
if (*fname == '/')
{
pstrcpy(namecopy,fname);
- strcpy(fname,".");
- strcat(fname,namecopy);
+ pstrcpy(fname,".");
+ pstrcat(fname,namecopy);
}
}
*p = 0;
else
*s = 0;
- strcat(s,s1);
+ pstrcat(s,s1);
}
trim_string(s,NULL,"\\..");
if(strncmp(s, "./", 2) == 0) {
trim_string(s, "./", NULL);
if(*s == 0)
- strcpy(s,"./");
+ pstrcpy(s,"./");
}
while ((p = strstr(s,"/../")) != NULL)
*p = 0;
else
*s = 0;
- strcat(s,s1);
+ pstrcat(s,s1);
}
trim_string(s,NULL,"/..");
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);
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));
}
if (strlen(s) == 0)
- strcpy(s,"./");
+ pstrcpy(s,"./");
return(True);
}
if (p && (p != base_name))
{
- strcat(newname,"/");
- strcat(newname,p+1);
+ pstrcat(newname,"/");
+ pstrcat(newname,p+1);
}
{
ChDir(wd);
if (strlen(s) == 0)
- strcpy(s,"./");
+ pstrcpy(s,"./");
DEBUG(3,("reduced to %s\n",s));
return(True);
}
else
{
- strcpy(mext,"");
+ pstrcpy(mext,"");
if (strlen(mbeg) > 8)
{
pstrcpy(mext,mbeg + 8);
}
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);
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));
}
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);
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);
{
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);
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;
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;
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;
}
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;
}
for processing.
****************************************************************************/
-typedef struct _message_list {
- struct _message_list *msg_next;
+typedef struct {
+ ubi_slNode msg_next;
char *msg_buf;
int msg_len;
} pending_message_list;
-static pending_message_list *smb_msg_head = NULL;
+static ubi_slList smb_oplock_queue = { NULL, (ubi_slNodePtr)&smb_oplock_queue, 0};
/****************************************************************************
- Function to push a linked list of local messages ready
+ Function to push a message onto the tail of a linked list of smb messages ready
for processing.
****************************************************************************/
-static BOOL push_local_message(pending_message_list **pml, char *buf, int msg_len)
+static BOOL push_local_message(ubi_slList *list_head, char *buf, int msg_len)
{
pending_message_list *msg = (pending_message_list *)
malloc(sizeof(pending_message_list));
if(msg == NULL)
{
- DEBUG(0,("push_message: malloc fail (1)\n"));
+ DEBUG(0,("push_local_message: malloc fail (1)\n"));
return False;
}
memcpy(msg->msg_buf, buf, msg_len);
msg->msg_len = msg_len;
- msg->msg_next = *pml;
- *pml = msg;
+ ubi_slAddTail( list_head, msg);
return True;
}
/****************************************************************************
- Function to push a linked list of local smb messages ready
+ Function to push a smb message onto a linked list of local smb messages ready
for processing.
****************************************************************************/
-BOOL push_smb_message(char *buf, int msg_len)
+BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
{
- return push_local_message(&smb_msg_head, buf, msg_len);
+ return push_local_message(&smb_oplock_queue, buf, msg_len);
}
/****************************************************************************
* If so - copy and return it.
*/
- if(smb_msg_head)
+ if(ubi_slCount(&smb_oplock_queue) != 0)
{
- pending_message_list *msg = smb_msg_head;
+ pending_message_list *msg = (pending_message_list *)ubi_slRemHead(&smb_oplock_queue);
memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
- smb_msg_head = msg->msg_next;
/* Free the message we just copied. */
free((char *)msg->msg_buf);
{
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));
}
return False;
}
- strcpy(*dest,src);
+ pstrcpy(*dest,src);
}
return(True);
}
return(ret);
}
-
-
/*********************************************************
-* Recursive routine that is called by mask_match.
-* Does the actual matching.
+* Recursive routine that is called by unix_mask_match.
+* Does the actual matching. This is the 'original code'
+* used by the unix matcher.
*********************************************************/
-BOOL do_match(char *str, char *regexp, int case_sig)
+static BOOL unix_do_match(char *str, char *regexp, int case_sig)
{
char *p;
while(*str) {
while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
str++;
- if(do_match(str,p,case_sig))
+ if(unix_do_match(str,p,case_sig))
return True;
if(!*str)
return False;
* Routine to match a given string with a regexp - uses
* simplified regexp that takes * and ? only. Case can be
* significant or not.
+* This is the 'original code' used by the unix matcher.
*********************************************************/
-BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
+
+static BOOL unix_mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
{
char *p;
pstring p1, p2;
StrnCpy(p2,str,sizeof(pstring)-1);
if (!strchr(p2,'.')) {
- strcat(p2,".");
+ pstrcat(p2,".");
}
-/*
- if (!strchr(p1,'.')) {
- strcat(p1,".");
- }
-*/
-
-#if 0
- if (strchr(p1,'.'))
- {
- string_sub(p1,"*.*","*");
- string_sub(p1,".*","*");
- }
-#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]);
+ (void)pstrcpy( &p[1], &p[2]);
if (strequal(p1,"*")) return(True);
- DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
+ DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
if (trans2) {
fstrcpy(ebase,p1);
}
}
- matched = do_match(sbase,ebase,case_sig) &&
- (trans2 || do_match(sext,eext,case_sig));
+ matched = unix_do_match(sbase,ebase,case_sig) &&
+ (trans2 || unix_do_match(sext,eext,case_sig));
- DEBUG(8,("mask_match returning %d\n", matched));
+ DEBUG(8,("unix_mask_match returning %d\n", matched));
return matched;
}
+/*********************************************************
+* Recursive routine that is called by mask_match.
+* Does the actual matching. Returns True if matched,
+* False if failed. This is the 'new' NT style matcher.
+*********************************************************/
+
+BOOL do_match(char *str, char *regexp, int case_sig)
+{
+ char *p;
+
+ for( p = regexp; *p && *str; ) {
+ switch(*p) {
+ case '?':
+ str++; p++;
+ break;
+
+ case '*':
+ /* Look for a character matching
+ the one after the '*' */
+ p++;
+ if(!*p)
+ return True; /* Automatic match */
+ while(*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;
+ }
+ } else {
+ if(toupper(*str) != toupper(*p)) {
+ return False;
+ }
+ }
+ str++, p++;
+ break;
+ }
+ }
+
+ if(!*p && !*str)
+ return True;
+
+ if (!*p && str[0] == '.' && str[1] == 0) {
+ return(True);
+ }
+
+ if (!*str && *p == '?') {
+ while (*p == '?')
+ p++;
+ return(!*p);
+ }
+
+ if(!*str && (*p == '*' && p[1] == '\0')) {
+ return True;
+ }
+
+ return False;
+}
+
+/*********************************************************
+* 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 <Harald.Ums@pro-sieben.de>
+* This is the new 'NT style' matcher.
+*********************************************************/
+
+BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
+{
+ char *p;
+ pstring t_pattern, t_filename, te_pattern, te_filename;
+ fstring ebase,eext,sbase,sext;
+
+ BOOL matched = False;
+
+ /* Make local copies of str and regexp */
+ pstrcpy(t_pattern,regexp);
+ pstrcpy(t_filename,str);
+
+#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(t_filename,'.')) {
+ pstrcat(t_filename,".");
+ }
+#endif
+
+ /* Remove any *? and ** as they are meaningless */
+ string_sub(t_pattern, "*?", "*");
+ string_sub(t_pattern, "**", "*");
+
+ if (strequal(t_pattern,"*"))
+ return(True);
+
+ 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 {
+
+ /* -------------------------------------------------
+ * 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 {
+
+ 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;
+ }
+
+ 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();
}
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;
char *p = strrchr(path,'\\');
if (!p)
- strcpy(buf,path);
+ pstrcpy(buf,path);
else
{
*p = 0;
- strcpy(buf,path);
+ pstrcpy(buf,path);
*p = '\\';
}
char *p = strrchr(path,'\\');
if (!p)
- strcpy(buf,path);
+ pstrcpy(buf,path);
else
- strcpy(buf,p+1);
+ pstrcpy(buf,p+1);
return(buf);
}
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)
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 );
if (ret < 0) {
DEBUG(1,("error connecting to %s:%d (%s)\n",
inet_ntoa(*addr),port,strerror(errno)));
+ close(res);
return -1;
}
if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
for (i=0; pure_address && str[i]; i++)
- if (!(isdigit(str[i]) || str[i] == '.'))
+ if (!(isdigit((int)str[i]) || str[i] == '.'))
pure_address = False;
/* if it's in the form of an IP address then get the lib to interpret it */
{
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);
+ }
}
/*******************************************************************
last_fd = fd;
global_client_name_done = False;
- strcpy(name_buf,"UNKNOWN");
+ pstrcpy(name_buf,"UNKNOWN");
if (fd == -1) {
return name_buf;
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)));
- strcpy(name_buf,"UNKNOWN");
+ pstrcpy(name_buf,"UNKNOWN");
}
}
global_client_name_done = True;
last_fd = fd;
global_client_addr_done = False;
- strcpy(addr_buf,"0.0.0.0");
+ fstrcpy(addr_buf,"0.0.0.0");
if (fd == -1) {
return addr_buf;
return addr_buf;
}
+#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
+/******************************************************************
+ Remove any mount options such as -rsize=2048,wsize=2048 etc.
+ Based on a fix from <Thomas.Hepper@icem.de>.
+*******************************************************************/
+
+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;
+
+ pstrcpy(tmp_str, p);
+ pstrcpy(*str, tmp_str);
+ }
+ }
+}
+
/*******************************************************************
Patch from jkf@soton.ac.uk
Split Luke's automount_server into YP lookup and string splitter
As we may end up doing both, cache the last YP result.
*******************************************************************/
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
-#ifdef NISPLUS
+#ifdef WITH_NISPLUS_HOME
static char *automount_lookup(char *user_name)
{
static fstring last_key = "";
if (strcmp(user_name, last_key))
{
- sprintf(buffer, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
+ 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))
}
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 */
+#else /* WITH_NISPLUS_HOME */
static char *automount_lookup(char *user_name)
{
static fstring last_key = "";
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 */
+#endif /* WITH_NISPLUS_HOME */
#endif
/*******************************************************************
static pstring server_name;
/* use the local machine name as the default */
- /* this will be the default if AUTOMOUNT is not used or fails */
+ /* this will be the default if WITH_AUTOMOUNT is not used or fails */
pstrcpy(server_name, local_machine);
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map())
{
static pstring server_path;
/* use the passwd entry as the default */
- /* this will be the default if AUTOMOUNT is not used or fails */
+ /* 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));
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
+#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map())
{
{
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);
}
}
#endif
{
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));
}
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 <branko.cibej@hermes.si> */
- 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 <branko.cibej@hermes.si> */
+ 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;
}
return;
}
+
+/****************************************************************************
+do some standard substitutions in a string
+****************************************************************************/
+void standard_sub(connection_struct *conn,char *str)
+{
+ char *p, *s, *home;
+
+ for (s=str; (p=strchr(s, '%'));s=p) {
+ switch (*(p+1)) {
+ case 'H':
+ if ((home = get_home_dir(conn->user))) {
+ string_sub(p,"%H",home);
+ } else {
+ p += 2;
+ }
+ break;
+
+ case 'P':
+ string_sub(p,"%P",conn->connectpath);
+ break;
+
+ case 'S':
+ string_sub(p,"%S",
+ lp_servicename(SNUM(conn)));
+ break;
+
+ case 'g':
+ string_sub(p,"%g",
+ gidtoname(conn->gid));
+ break;
+ case 'u':
+ string_sub(p,"%u",conn->user);
+ break;
+
+ /* Patch from jkf@soton.ac.uk Left the %N (NIS
+ * server name) in standard_sub_basic as it is
+ * a feature for logon servers, hence uses the
+ * username. The %p (NIS server path) code is
+ * here as it is used instead of the default
+ * "path =" string in [homes] and so needs the
+ * service name, not the username. */
+ case 'p':
+ string_sub(p,"%p",
+ automount_path(lp_servicename(SNUM(conn))));
+ break;
+ case '\0':
+ p++;
+ break; /* don't run off the end of the string
+ */
+
+ default: p+=2;
+ break;
+ }
+ }
+
+ standard_sub_basic(str);
+}
+
+
+
/*******************************************************************
are two IPs on the same subnet?
********************************************************************/
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);
}
********************************************************************/
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);
+ static char name[40];
+ struct group *grp = getgrgid(gid);
+ if (grp) return(grp->gr_name);
+ slprintf(name,sizeof(name) - 1, "%d",gid);
+ return(name);
}
/*******************************************************************
-block sigs
+something really nasty happened - panic!
********************************************************************/
-void BlockSignals(BOOL block,int signum)
+void smb_panic(char *why)
{
-#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
+ char *cmd = lp_panic_action();
+ if (cmd && *cmd) {
+ system(cmd);
+ exit(1);
+ }
}
-#if AJT
-/*******************************************************************
-my own panic function - not suitable for general use
-********************************************************************/
-void ajt_panic(void)
-{
- system("/usr/bin/X11/xedit -display solen: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
********************************************************************/
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);
}
/*******************************************************************
{
if(namelist->is_wild)
{
- /* look for a wildcard match. */
- if (mask_match(last_component, namelist->name, case_sensitive, False))
+ /*
+ * Look for a wildcard match. Use the old
+ * 'unix style' mask match, rather than the
+ * new NT one.
+ */
+ if (unix_mask_match(last_component, namelist->name, case_sensitive, False))
{
DEBUG(8,("is_in_path: mask match succeeded\n"));
return True;
struct flock lock;
int ret;
-#if 1
- uint32 mask = 0xC0000000;
-
- /* make sure the count is reasonable, we might kill the lockd otherwise */
- count &= ~mask;
+ /*
+ * FIXME.
+ * NB - this code will need re-writing to cope with large (64bit)
+ * lock requests. JRA.
+ */
- /* the offset is often strange - remove 2 of its bits if either of
- the top two bits are set. Shift the top ones by two bits. This
- still allows OLE2 apps to operate, but should stop lockd from
- dieing */
- if ((offset & mask) != 0)
- offset = (offset & ~mask) | ((offset & mask) >> 2);
-#else
- uint32 mask = ((unsigned)1<<31);
+ if(lp_ole_locking_compat()) {
+ uint32 mask = 0xC0000000;
- /* interpret negative counts as large numbers */
- if (count < 0)
+ /* make sure the count is reasonable, we might kill the lockd otherwise */
count &= ~mask;
- /* no negative offsets */
- offset &= ~mask;
+ /* the offset is often strange - remove 2 of its bits if either of
+ the top two bits are set. Shift the top ones by two bits. This
+ still allows OLE2 apps to operate, but should stop lockd from
+ dieing */
+ if ((offset & mask) != 0)
+ offset = (offset & ~mask) | ((offset & mask) >> 2);
+ } else {
+ uint32 mask = ((unsigned)1<<31);
+ int32 s_count = (int32) count; /* Signed count. */
+ int32 s_offset = (int32)offset; /* Signed offset. */
+
+ /* interpret negative counts as large numbers */
+ if (s_count < 0)
+ s_count &= ~mask;
- /* count + offset must be in range */
- while ((offset < 0 || (offset + count < 0)) && mask)
+ /* no negative offsets */
+ if(s_offset < 0)
+ s_offset &= ~mask;
+
+ /* count + offset must be in range */
+ while ((s_offset < 0 || (s_offset + s_count < 0)) && mask)
{
- offset &= ~mask;
+ s_offset &= ~mask;
mask = mask >> 1;
}
-#endif
+
+ offset = (uint32)s_offset;
+ count = (uint32)s_count;
+ }
DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
(lock.l_pid != 0) &&
(lock.l_pid != getpid()))
{
- DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
+ DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
return(True);
}
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;
}
}
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
}
/*****************************************************************
- Convert a domain SID to an ascii string. (non-reentrant).
+ Convert a SID to an ascii string.
*****************************************************************/
-/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-char *dom_sid_to_string(DOM_SID *sid)
+char *sid_to_string(pstring sidstr_out, DOM_SID *sid)
{
- static pstring sidstr;
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);
- sprintf(sidstr, "S-%d-%d", sid->sid_rev_num, ia);
+ slprintf(sidstr_out, sizeof(pstring) - 1, "S-%d-%d", sid->sid_rev_num, ia);
for (i = 0; i < sid->num_auths; i++)
{
- sprintf(subauth, "-%d", sid->sub_auths[i]);
- strcat(sidstr, subauth);
+ slprintf(subauth, sizeof(subauth)-1, "-%d", sid->sub_auths[i]);
+ pstrcat(sidstr_out, subauth);
}
- DEBUG(7,("dom_sid_to_string returning %s\n", sidstr));
- return sidstr;
+ 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;
+}
+
+/*****************************************************************************
+ * Provide a checksum on a string
+ *
+ * Input: s - the nul-terminated character string for which the checksum
+ * will be calculated.
+ *
+ * Output: The checksum value calculated for s.
+ *
+ * ****************************************************************************
+ */
+int str_checksum(char *s)
+{
+ int res = 0;
+ int c;
+ int i=0;
+
+ while(*s) {
+ c = *s;
+ res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
+ s++;
+ i++;
+ }
+ return(res);
+} /* str_checksum */