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:
parent
d838452413
commit
359d42c08d
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user