1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3/lib/system.c

414 lines
10 KiB
C
Raw Normal View History

/*
Unix SMB/Netbios implementation.
Version 1.9.
Samba system utilities
'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6)
1997-05-08 05:14:17 +04:00
Copyright (C) Andrew Tridgell 1992-1997
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
extern int DEBUGLEVEL;
/*
The idea is that this file will eventually have wrappers around all
important system calls in samba. The aims are:
- to enable easier porting by putting OS dependent stuff in here
- to allow for hooks into other "pseudo-filesystems"
- to allow easier integration of things like the japanese extensions
- to support the philosophy of Samba to expose the features of
the OS within the SMB model. In general whatever file/printer/variable
expansions/etc make sense to the OS should be acceptable to Samba.
*/
/*******************************************************************
this replaces the normal select() system call
return if some data has arrived on one of the file descriptors
return -1 means error
********************************************************************/
#ifdef NO_SELECT
static int pollfd(int fd)
{
int r=0;
#ifdef HAS_RDCHK
r = rdchk(fd);
#elif defined(TCRDCHK)
(void)ioctl(fd, TCRDCHK, &r);
#else
(void)ioctl(fd, FIONREAD, &r);
#endif
return(r);
}
int sys_select(fd_set *fds,struct timeval *tval)
{
fd_set fds2;
int counter=0;
int found=0;
FD_ZERO(&fds2);
while (1)
{
int i;
for (i=0;i<255;i++) {
if (FD_ISSET(i,fds) && pollfd(i)>0) {
found++;
FD_SET(i,&fds2);
}
}
if (found) {
memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
return(found);
}
if (tval && tval->tv_sec < counter) return(0);
sleep(1);
counter++;
}
}
#else
int sys_select(fd_set *fds,struct timeval *tval)
{
struct timeval t2;
int selrtn;
do {
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
errno = 0;
selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
} while (selrtn<0 && errno == EINTR);
return(selrtn);
}
#endif
/*******************************************************************
just a unlink wrapper
********************************************************************/
int sys_unlink(char *fname)
{
return(unlink(dos_to_unix(fname,False)));
}
/*******************************************************************
a simple open() wrapper
********************************************************************/
int sys_open(char *fname,int flags,int mode)
{
return(open(dos_to_unix(fname,False),flags,mode));
}
/*******************************************************************
a simple opendir() wrapper
********************************************************************/
DIR *sys_opendir(char *dname)
{
return(opendir(dos_to_unix(dname,False)));
}
/*******************************************************************
and a stat() wrapper
********************************************************************/
int sys_stat(char *fname,struct stat *sbuf)
{
return(stat(dos_to_unix(fname,False),sbuf));
}
/*******************************************************************
The wait() calls vary between systems
********************************************************************/
int sys_waitpid(pid_t pid,int *status,int options)
{
#ifdef USE_WAITPID
return waitpid(pid,status,options);
#else /* USE_WAITPID */
return wait4(pid, status, options, NULL);
#endif /* USE_WAITPID */
}
/*******************************************************************
don't forget lstat()
********************************************************************/
int sys_lstat(char *fname,struct stat *sbuf)
{
return(lstat(dos_to_unix(fname,False),sbuf));
}
/*******************************************************************
mkdir() gets a wrapper
********************************************************************/
int sys_mkdir(char *dname,int mode)
{
return(mkdir(dos_to_unix(dname,False),mode));
}
/*******************************************************************
do does rmdir()
********************************************************************/
int sys_rmdir(char *dname)
{
return(rmdir(dos_to_unix(dname,False)));
}
/*******************************************************************
I almost forgot chdir()
********************************************************************/
int sys_chdir(char *dname)
{
return(chdir(dos_to_unix(dname,False)));
}
/*******************************************************************
now for utime()
********************************************************************/
int sys_utime(char *fname,struct utimbuf *times)
{
return(utime(dos_to_unix(fname,False),times));
}
/*********************************************************
for rename across filesystems Patch from Warren Birnbaum
<warrenb@hpcvscdp.cv.hp.com>
**********************************************************/
static int copy_reg(char *source, const char *dest)
{
struct stat source_stats;
int ifd;
int full_write();
int safe_read();
int ofd;
char *buf;
int len; /* Number of bytes read into `buf'. */
lstat (source, &source_stats);
if (!S_ISREG (source_stats.st_mode))
{
return 1;
}
if (unlink (dest) && errno != ENOENT)
{
return 1;
}
if((ifd = open (source, O_RDONLY, 0)) < 0)
{
return 1;
}
if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
{
close (ifd);
return 1;
}
if((buf = malloc( COPYBUF_SIZE )) == NULL)
{
close (ifd);
close (ofd);
unlink (dest);
return 1;
}
while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
{
if (write_data(ofd, buf, len) < 0)
{
close (ifd);
close (ofd);
unlink (dest);
free(buf);
return 1;
}
}
free(buf);
if (len < 0)
{
close (ifd);
close (ofd);
unlink (dest);
return 1;
}
if (close (ifd) < 0)
{
close (ofd);
return 1;
}
if (close (ofd) < 0)
{
return 1;
}
/* chown turns off set[ug]id bits for non-root,
so do the chmod last. */
/* Try to copy the old file's modtime and access time. */
{
struct utimbuf tv;
tv.actime = source_stats.st_atime;
tv.modtime = source_stats.st_mtime;
if (utime (dest, &tv))
{
return 1;
}
}
/* Try to preserve ownership. For non-root it might fail, but that's ok.
But root probably wants to know, e.g. if NFS disallows it. */
if (chown (dest, source_stats.st_uid, source_stats.st_gid)
&& (errno != EPERM))
{
return 1;
}
if (chmod (dest, source_stats.st_mode & 07777))
{
return 1;
}
unlink (source);
return 0;
}
/*******************************************************************
for rename()
********************************************************************/
int sys_rename(char *from, char *to)
{
int rcode;
pstring zfrom, zto;
pstrcpy (zfrom, dos_to_unix (from, False));
pstrcpy (zto, dos_to_unix (to, False));
rcode = rename (zfrom, zto);
if (errno == EXDEV)
{
/* Rename across filesystems needed. */
rcode = copy_reg (zfrom, zto);
}
return rcode;
}
/*******************************************************************
for chmod
********************************************************************/
int sys_chmod(char *fname,int mode)
{
return(chmod(dos_to_unix(fname,False),mode));
}
/*******************************************************************
for getwd
********************************************************************/
char *sys_getwd(char *s)
{
char *wd;
#ifdef USE_GETCWD
wd = (char *) getcwd (s, sizeof (pstring));
#else
wd = (char *) getwd (s);
#endif
if (wd)
unix_to_dos (wd, True);
return wd;
}
/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
int sys_chown(char *fname,int uid,int gid)
{
#ifdef NO_CHOWN
DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
#else
return(chown(fname,uid,gid));
#endif
}
/*******************************************************************
os/2 also doesn't have chroot
********************************************************************/
int sys_chroot(char *dname)
{
#ifdef NO_CHROOT
DEBUG(1,("Warning - chroot(%s) not done\n",dname));
#else
return(chroot(dname));
#endif
}
/**************************************************************************
A wrapper for gethostbyname() that tries avoids looking up hostnames
in the root domain, which can cause dial-on-demand links to come up for no
apparent reason.
****************************************************************************/
struct hostent *sys_gethostbyname(char *name)
{
#ifdef REDUCE_ROOT_DNS_LOOKUPS
char query[256], hostname[256];
char *domain;
/* Does this name have any dots in it? If so, make no change */
if (strchr(name, '.'))
return(gethostbyname(name));
/* Get my hostname, which should have domain name
attached. If not, just do the gethostname on the
original string.
*/
gethostname(hostname, sizeof(hostname) - 1);
hostname[sizeof(hostname) - 1] = 0;
if ((domain = strchr(hostname, '.')) == NULL)
return(gethostbyname(name));
/* Attach domain name to query and do modified query.
If names too large, just do gethostname on the
original string.
*/
if((strlen(name) + strlen(domain)) >= sizeof(query))
return(gethostbyname(name));
sprintf(query, "%s%s", name, domain);
return(gethostbyname(query));
#else /* REDUCE_ROOT_DNS_LOOKUPS */
return(gethostbyname(name));
#endif /* REDUCE_ROOT_DNS_LOOKUPS */
}