1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

ipc.c: Adding Andrews become_root code to the main branch.

locking.c: Adding Andrews become_root code to the main branch.
pipes.c: Fixing the close_file issue.
proto.h: The usual.
reply.c: Move smb_pass into NTDOMAIN defined code. Fixing the close_file issue.
server.c: Fixing the close_file issue.
trans2.c: Fixing the close_file issue.
uid.c: Adding Andrews become_root code to the main branch.
Jeremy (jallison@whistle.com)
(This used to be commit 16fd4337f79ce33f91050c96c4a566221c5d9126)
This commit is contained in:
Jeremy Allison 1997-10-15 21:53:59 +00:00
parent d838452413
commit 359d42c08d
8 changed files with 125 additions and 52 deletions

View File

@ -776,7 +776,7 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize);
int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
BOOL check_name(char *name,int cnum);
void sync_file(int fnum);
void close_file(int fnum);
void close_file(int fnum, BOOL normal_close);
BOOL check_file_sharing(int cnum,char *fname);
int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
BOOL fcbopen, int *flags);
@ -957,6 +957,8 @@ BOOL become_guest(void);
BOOL become_user(int cnum, uint16 vuid);
BOOL unbecome_user(void );
int smbrun(char *cmd,char *outfile,BOOL shared);
void become_root(BOOL save_dir) ;
void unbecome_root(BOOL restore_dir);
/*The following definitions come from username.c */

View File

@ -729,10 +729,12 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok
if(!share_name(cnum, dev, inode, fname))
return False;
/* we need to do this as root */
become_root(False);
{
int old_umask;
BOOL gotlock = False;
unbecome_user();
old_umask = umask(0);
/*
@ -801,23 +803,13 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok
*/
umask(old_umask);
if(!become_user(cnum,Connections[cnum].vuid))
{
DEBUG(0,("lock_share_entry: Can't become connected user!\n"));
close(fd);
ret = False;
}
/* We need to change directory back to the connection root. */
if (ChDir(Connections[cnum].connectpath) != 0)
{
DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n",
Connections[cnum].connectpath, strerror(errno)));
close(fd);
ret = False;
}
}
*ptok = (share_lock_token)fd;
/* return to our previous privilage level */
unbecome_root(False);
return ret;
}
@ -848,27 +840,22 @@ Force a share file to be deleted.
static int delete_share_file( int cnum, char *fname )
{
unbecome_user();
/* the share file could be owned by anyone, so do this as root */
become_root(False);
if(unlink(fname) != 0)
{
DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
fname, strerror(errno)));
}
else
{
DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
}
DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
/* return to our previous privilage level */
unbecome_root(False);
if(!become_user(cnum,Connections[cnum].vuid))
{
DEBUG(0,("delete_share_file: Can't become connected user!\n"));
return -1;
}
/* We need to change directory back to the connection root. */
if (ChDir(Connections[cnum].connectpath) != 0)
{
DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n",
Connections[cnum].connectpath, strerror(errno)));
return -1;
}
return 0;
}

View File

@ -1602,6 +1602,8 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
DEBUG(3,("Setting print name to %s\n",name));
become_root(True);
for (i=0;i<MAX_OPEN_FILES;i++)
if (Files[i].open && Files[i].print_file)
{
@ -1617,6 +1619,8 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
string_set(&Files[i].name,name);
break;
}
unbecome_root(True);
}
desc.errcode=NERR_Success;

View File

@ -147,7 +147,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -155,7 +155,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
fmode = dos_mode(cnum,fname,&sbuf);
mtime = sbuf.st_mtime;
if (fmode & aDIR) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}

View File

@ -479,8 +479,8 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
/* computer with that name (minus the $) has access. For now */
/* say yes to everything ending in $. */
if (user[strlen(user) - 1] == '$') {
struct smb_passwd *smb_pass; /* To check if machine account exists */
#ifdef NTDOMAIN
struct smb_passwd *smb_pass; /* To check if machine account exists */
/*
PAXX: Ack. We don't want to do this. The workstation trust account
with a $ on the end should exist in the local password database
@ -1178,7 +1178,7 @@ int reply_open(char *inbuf,char *outbuf)
}
if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -1188,7 +1188,7 @@ int reply_open(char *inbuf,char *outbuf)
if (fmode & aDIR) {
DEBUG(3,("attempt to open a directory %s\n",fname));
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -1274,7 +1274,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
}
if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -1282,7 +1282,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
fmode = dos_mode(cnum,fname,&sbuf);
mtime = sbuf.st_mtime;
if (fmode & aDIR) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -1328,7 +1328,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
int i;
for (i=0;i<MAX_OPEN_FILES;i++)
if (Files[i].uid == vuser->uid && Files[i].open) {
close_file(i);
close_file(i,False);
}
}
@ -2271,7 +2271,7 @@ int reply_close(char *inbuf,char *outbuf)
/* try and set the date */
set_filetime(Files[fnum].name,mtime);
close_file(fnum);
close_file(fnum,True);
/* We have a cached error */
if(eclass || err)
@ -2318,7 +2318,7 @@ int reply_writeclose(char *inbuf,char *outbuf)
set_filetime(Files[fnum].name,mtime);
close_file(fnum);
close_file(fnum,True);
DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
timestring(),fnum,cnum,numtowrite,nwritten,
@ -2550,7 +2550,7 @@ int reply_printclose(char *inbuf,char *outbuf)
if (!CAN_PRINT(cnum))
return(ERROR(ERRDOS,ERRnoaccess));
close_file(fnum);
close_file(fnum,True);
DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum));
@ -3187,14 +3187,14 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
fnum2 = find_free_file();
if (fnum2<0) {
close_file(fnum1);
close_file(fnum1,False);
return(False);
}
open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1,
ofun,st.st_mode,0,&Access,&action);
if (!Files[fnum2].open) {
close_file(fnum1);
close_file(fnum1,False);
return(False);
}
@ -3205,8 +3205,8 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
if (st.st_size)
ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0);
close_file(fnum1);
close_file(fnum2);
close_file(fnum1,False);
close_file(fnum2,False);
return(ret == st.st_size);
}

View File

@ -1361,8 +1361,13 @@ static void check_magic(int fnum,int cnum)
/****************************************************************************
close a file - possibly invalidating the read prediction
If normal_close is 1 then this came from a normal SMBclose (or equivalent)
operation otherwise it came as the result of some other operation such as
the closing of the connection. In the latter case printing and
magic scripts are not run
****************************************************************************/
void close_file(int fnum)
void close_file(int fnum, BOOL normal_close)
{
files_struct *fs_p = &Files[fnum];
int cnum = fs_p->cnum;
@ -1399,11 +1404,12 @@ void close_file(int fnum)
unlock_share_entry( cnum, dev, inode, token);
/* NT uses smbclose to start a print - weird */
if (fs_p->print_file)
if (normal_close && fs_p->print_file)
print_file(fnum);
/* check for magic scripts */
check_magic(fnum,cnum);
if (normal_close)
check_magic(fnum,cnum);
DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
timestring(),Connections[cnum].user,fs_p->name,
@ -1575,7 +1581,7 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
if (*share_locked && lp_share_modes(SNUM(cnum)))
unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
Files[fnum].fd_ptr->inode, token);
close_file(fnum);
close_file(fnum,False);
/* Share mode no longer locked. */
*share_locked = False;
errno = EACCES;
@ -3847,7 +3853,7 @@ static void close_open_files(int cnum)
int i;
for (i=0;i<MAX_OPEN_FILES;i++)
if( Files[i].cnum == cnum && Files[i].open) {
close_file(i);
close_file(i,False);
}
}

View File

@ -226,7 +226,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
}
if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}
@ -235,7 +235,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
mtime = sbuf.st_mtime;
inode = sbuf.st_ino;
if (fmode & aDIR) {
close_file(fnum);
close_file(fnum,False);
return(ERROR(ERRDOS,ERRnoaccess));
}

View File

@ -481,3 +481,77 @@ int smbrun(char *cmd,char *outfile,BOOL shared)
#endif
return 1;
}
static struct current_user current_user_saved;
static int become_root_depth;
static pstring become_root_dir;
/****************************************************************************
This is used when we need to do a privilaged operation (such as mucking
with share mode files) and temporarily need root access to do it. This
call should always be paired with an unbecome_root() call immediately
after the operation
Set save_dir if you also need to save/restore the CWD
****************************************************************************/
void become_root(BOOL save_dir)
{
if (become_root_depth) {
DEBUG(0,("ERROR: become root depth is non zero\n"));
}
if (save_dir)
GetWd(become_root_dir);
current_user_saved = current_user;
become_root_depth = 1;
become_gid(0);
become_uid(0);
}
/****************************************************************************
When the privilaged operation is over call this
Set save_dir if you also need to save/restore the CWD
****************************************************************************/
void unbecome_root(BOOL restore_dir)
{
if (become_root_depth != 1) {
DEBUG(0,("ERROR: unbecome root depth is %d\n",
become_root_depth));
}
/* we might have done a become_user() while running as root,
if we have then become root again in order to become
non root! */
if (current_user.uid != 0) {
become_uid(0);
}
/* restore our gid first */
if (!become_gid(current_user_saved.gid)) {
DEBUG(0,("ERROR: Failed to restore gid\n"));
exit_server("Failed to restore gid");
}
#ifndef NO_SETGROUPS
if (current_user_saved.ngroups > 0) {
if (setgroups(current_user_saved.ngroups,
current_user_saved.groups)<0)
DEBUG(0,("ERROR: setgroups call failed!\n"));
}
#endif
/* now restore our uid */
if (!become_uid(current_user_saved.uid)) {
DEBUG(0,("ERROR: Failed to restore uid\n"));
exit_server("Failed to restore uid");
}
if (restore_dir)
ChDir(become_root_dir);
current_user = current_user_saved;
become_root_depth = 0;
}