mirror of
https://github.com/samba-team/samba.git
synced 2025-03-10 12:58:35 +03:00
Merge the become_XXX -> change_to_XXX fixes from 2.2.2 to HEAD.
Ensure make_conection() can only be called as root. Jeremy. (This used to be commit 8d23a7441b4687458ee021bfe8880558506eddba)
This commit is contained in:
parent
9a903a08a7
commit
c416ff851b
@ -233,7 +233,7 @@ static BOOL dfs_auth(char *user, char *password)
|
||||
}
|
||||
|
||||
/*
|
||||
* NB. I'd like to change these to call something like become_user()
|
||||
* NB. I'd like to change these to call something like change_to_user()
|
||||
* instead but currently we don't have a connection
|
||||
* context to become the correct user. This is already
|
||||
* fairly platform specific code however, so I think
|
||||
|
@ -297,7 +297,7 @@ static BOOL make_sam_from_nisp_object(struct sam_passwd *pw_buf, nis_object *obj
|
||||
if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$') {
|
||||
|
||||
/* XXXX hack to get standard_sub_basic() to use sam logon username */
|
||||
/* possibly a better way would be to do a become_user() call */
|
||||
/* possibly a better way would be to do a change_to_user() call */
|
||||
pstrcpy(samlogon_user, pw_buf->smb_name);
|
||||
sam_logon_in_ssb = True;
|
||||
|
||||
|
@ -233,7 +233,7 @@ static BOOL dfs_auth(char *user, char *password)
|
||||
}
|
||||
|
||||
/*
|
||||
* NB. I'd like to change these to call something like become_user()
|
||||
* NB. I'd like to change these to call something like change_to_user()
|
||||
* instead but currently we don't have a connection
|
||||
* context to become the correct user. This is already
|
||||
* fairly platform specific code however, so I think
|
||||
|
@ -944,7 +944,10 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
|
||||
/* connect to the print$ share under the same account as the user connected to the rpc pipe */
|
||||
/* Null password is ok - we are already an authenticated user... */
|
||||
*null_pw = '\0';
|
||||
|
||||
become_root();
|
||||
conn = make_connection("print$", null_pw, 0, "A:", user->vuid, &nt_status);
|
||||
unbecome_root();
|
||||
|
||||
if (conn == NULL) {
|
||||
DEBUG(0,("get_correct_cversion: Unable to connect\n"));
|
||||
@ -952,13 +955,9 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Save who we are - we are temporarily becoming the connection user. */
|
||||
push_sec_ctx();
|
||||
|
||||
if (!become_user(conn, conn->vuid)) {
|
||||
DEBUG(0,("get_correct_cversion: Can't become user!\n"));
|
||||
*perr = WERR_ACCESS_DENIED;
|
||||
pop_sec_ctx();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1017,16 +1016,16 @@ static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
|
||||
|
||||
close_file(fsp, True);
|
||||
close_cnum(conn, user->vuid);
|
||||
pop_sec_ctx();
|
||||
unbecome_user();
|
||||
return cversion;
|
||||
|
||||
error_exit:
|
||||
|
||||
error_exit:
|
||||
if(fsp)
|
||||
close_file(fsp, True);
|
||||
|
||||
close_cnum(conn, user->vuid);
|
||||
pop_sec_ctx();
|
||||
unbecome_user();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -708,7 +708,7 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
|
||||
usr_info->ptr_user_info = 0;
|
||||
|
||||
/* XXXX hack to get standard_sub_basic() to use sam logon username */
|
||||
/* possibly a better way would be to do a become_user() call */
|
||||
/* possibly a better way would be to do a change_to_user() call */
|
||||
sam_logon_in_ssb = True;
|
||||
pstrcpy(samlogon_user, nt_username);
|
||||
|
||||
|
@ -1135,7 +1135,6 @@ BOOL api_pipe_request(pipes_struct *p)
|
||||
{
|
||||
int i = 0;
|
||||
BOOL ret = False;
|
||||
BOOL changed_user_id = False;
|
||||
|
||||
if (p->ntlmssp_auth_validated) {
|
||||
|
||||
@ -1143,8 +1142,6 @@ BOOL api_pipe_request(pipes_struct *p)
|
||||
prs_mem_free(&p->out_data.rdata);
|
||||
return False;
|
||||
}
|
||||
|
||||
changed_user_id = True;
|
||||
}
|
||||
|
||||
for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
|
||||
@ -1157,8 +1154,8 @@ BOOL api_pipe_request(pipes_struct *p)
|
||||
}
|
||||
}
|
||||
|
||||
if(changed_user_id)
|
||||
unbecome_authenticated_pipe_user(p);
|
||||
if(p->ntlmssp_auth_validated)
|
||||
unbecome_authenticated_pipe_user();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1598,7 +1598,9 @@ NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDE
|
||||
|
||||
get_current_user(&user, p);
|
||||
|
||||
become_root();
|
||||
conn = make_connection(qualname, null_pw, 0, "A:", user.vuid, &nt_status);
|
||||
unbecome_root();
|
||||
|
||||
if (conn == NULL) {
|
||||
DEBUG(3,("_srv_net_file_query_secdesc: Unable to connect to %s\n", qualname));
|
||||
@ -1649,7 +1651,7 @@ NTSTATUS _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDE
|
||||
psd->dacl->revision = (uint16) NT4_ACL_REVISION;
|
||||
|
||||
close_file(fsp, True);
|
||||
|
||||
unbecome_user();
|
||||
close_cnum(conn, user.vuid);
|
||||
return r_u->status;
|
||||
|
||||
@ -1700,7 +1702,9 @@ NTSTATUS _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *
|
||||
|
||||
get_current_user(&user, p);
|
||||
|
||||
become_root();
|
||||
conn = make_connection(qualname, null_pw, 0, "A:", user.vuid, &nt_status);
|
||||
unbecome_root();
|
||||
|
||||
if (conn == NULL) {
|
||||
DEBUG(3,("_srv_net_file_set_secdesc: Unable to connect to %s\n", qualname));
|
||||
|
@ -582,7 +582,7 @@ void process_blocking_lock_queue(time_t t)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!become_user(conn,vuid)) {
|
||||
if(!change_to_user(conn,vuid)) {
|
||||
DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
|
||||
vuid ));
|
||||
/*
|
||||
@ -594,7 +594,7 @@ void process_blocking_lock_queue(time_t t)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!become_service(conn,True)) {
|
||||
if(!set_current_service(conn,True)) {
|
||||
DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
|
||||
/*
|
||||
* Remove the entry and return an error to the client.
|
||||
@ -602,7 +602,7 @@ void process_blocking_lock_queue(time_t t)
|
||||
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
|
||||
free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
|
||||
blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -615,11 +615,11 @@ void process_blocking_lock_queue(time_t t)
|
||||
if(blocking_lock_record_process(blr)) {
|
||||
free_blocking_lock_record((blocking_lock_record *)ubi_slRemNext( &blocking_lock_queue, prev));
|
||||
blr = (blocking_lock_record *)(prev ? ubi_slNext(prev) : ubi_slFirst(&blocking_lock_queue));
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
continue;
|
||||
}
|
||||
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
|
||||
/*
|
||||
* Move to the next in the list.
|
||||
|
@ -126,16 +126,19 @@ static void *hash_register_notify(connection_struct *conn, char *path, uint32 fl
|
||||
Check if a change notify should be issued.
|
||||
A time of zero means instantaneous check - don't modify the last check time.
|
||||
*****************************************************************************/
|
||||
|
||||
static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *datap, time_t t)
|
||||
{
|
||||
struct change_data *data = (struct change_data *)datap;
|
||||
struct change_data data2;
|
||||
|
||||
if (t && t < data->last_check_time + lp_change_notify_timeout()) return False;
|
||||
if (t && t < data->last_check_time + lp_change_notify_timeout())
|
||||
return False;
|
||||
|
||||
if (!become_user(conn,vuid)) return True;
|
||||
if (!become_service(conn,True)) {
|
||||
unbecome_user();
|
||||
if (!change_to_user(conn,vuid))
|
||||
return True;
|
||||
if (!set_current_service(conn,True)) {
|
||||
change_to_root_user();
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -144,14 +147,14 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,
|
||||
data2.status_time != data->status_time ||
|
||||
data2.total_time != data->total_time ||
|
||||
data2.num_entries != data->num_entries) {
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
return True;
|
||||
}
|
||||
|
||||
if (t)
|
||||
data->last_check_time = t;
|
||||
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
|
||||
return False;
|
||||
}
|
||||
|
@ -750,7 +750,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
|
||||
saved_vuid = current_user.vuid;
|
||||
saved_fsp_conn = fsp->conn;
|
||||
vfs_GetWd(saved_fsp_conn,saved_dir);
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
/* Save the chain fnum. */
|
||||
file_chain_save();
|
||||
|
||||
@ -823,7 +823,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
|
||||
* Go back to being the user who requested the oplock
|
||||
* break.
|
||||
*/
|
||||
if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !become_user(saved_user_conn, saved_vuid))
|
||||
if((saved_user_conn != NULL) && (saved_vuid != UID_FIELD_INVALID) && !change_to_user(saved_user_conn, saved_vuid))
|
||||
{
|
||||
DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
|
||||
DEBUGADD( 0, ( "Shutting down server\n" ) );
|
||||
|
@ -244,7 +244,7 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
|
||||
vuser->groups = NULL;
|
||||
|
||||
/* Find all the groups this uid is in and store them.
|
||||
Used by become_user() */
|
||||
Used by change_to_user() */
|
||||
initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid);
|
||||
get_current_groups( &vuser->n_groups, &vuser->groups);
|
||||
|
||||
|
@ -120,7 +120,7 @@ static void async_processing(fd_set *fds, char *buffer, int buffer_len)
|
||||
|
||||
/* check for sighup processing */
|
||||
if (reload_after_sighup) {
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
DEBUG(1,("Reloading services after SIGHUP\n"));
|
||||
reload_services(False);
|
||||
reload_after_sighup = False;
|
||||
@ -702,7 +702,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
|
||||
|
||||
/* does this protocol need to be run as root? */
|
||||
if (!(flags & AS_USER))
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
|
||||
/* does this protocol need a valid tree connection? */
|
||||
if ((flags & AS_USER) && !conn) {
|
||||
@ -711,7 +711,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
|
||||
|
||||
|
||||
/* does this protocol need to be run as the connected user? */
|
||||
if ((flags & AS_USER) && !become_user(conn,session_tag)) {
|
||||
if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
|
||||
if (flags & AS_GUEST)
|
||||
flags &= ~AS_USER;
|
||||
else
|
||||
@ -734,13 +734,13 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
|
||||
}
|
||||
|
||||
/* load service specific parameters */
|
||||
if (conn && !become_service(conn,(flags & AS_USER)?True:False)) {
|
||||
if (conn && !set_current_service(conn,(flags & AS_USER)?True:False)) {
|
||||
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||
}
|
||||
|
||||
/* does this protocol need to be run as guest? */
|
||||
if ((flags & AS_GUEST) &&
|
||||
(!become_guest() ||
|
||||
(!change_to_guest() ||
|
||||
!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1)))) {
|
||||
return(ERROR_DOS(ERRSRV,ERRaccess));
|
||||
}
|
||||
@ -1096,7 +1096,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
|
||||
last_idle_closed_check = t;
|
||||
|
||||
/* become root again if waiting */
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
|
||||
/* check if we need to reload services */
|
||||
check_reload(t);
|
||||
|
@ -59,10 +59,8 @@ static BOOL become_uid(uid_t uid)
|
||||
/* Set effective user id */
|
||||
|
||||
set_effective_uid(uid);
|
||||
current_user.uid = uid;
|
||||
|
||||
DO_PROFILE_INC(uid_changes);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -88,8 +86,6 @@ static BOOL become_gid(gid_t gid)
|
||||
/* Set effective group id */
|
||||
|
||||
set_effective_gid(gid);
|
||||
current_user.gid = gid;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ max can be %d\n",
|
||||
|
||||
/* check for sighup processing */
|
||||
if (reload_after_sighup) {
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
DEBUG(1,("Reloading services after SIGHUP\n"));
|
||||
reload_services(False);
|
||||
reload_after_sighup = False;
|
||||
@ -393,7 +393,7 @@ BOOL reload_services(BOOL test)
|
||||
reset_stat_cache();
|
||||
|
||||
/* this forces service parameters to be flushed */
|
||||
become_service(NULL,True);
|
||||
set_current_service(NULL,True);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -479,10 +479,11 @@ void exit_server(char *reason)
|
||||
extern char *last_inbuf;
|
||||
|
||||
|
||||
if (!firsttime) exit(0);
|
||||
if (!firsttime)
|
||||
exit(0);
|
||||
firsttime = 0;
|
||||
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
DEBUG(2,("Closing connections\n"));
|
||||
|
||||
conn_close_all();
|
||||
|
@ -34,9 +34,10 @@ extern fstring remote_machine;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
load parameters specific to a connection/service
|
||||
Load parameters specific to a connection/service.
|
||||
****************************************************************************/
|
||||
BOOL become_service(connection_struct *conn,BOOL do_chdir)
|
||||
|
||||
BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
|
||||
{
|
||||
extern char magic_char;
|
||||
static connection_struct *last_conn;
|
||||
@ -315,10 +316,10 @@ static void set_admin_user(connection_struct *conn)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
make a connection to a service
|
||||
Make a connection to a service.
|
||||
****************************************************************************/
|
||||
|
||||
connection_struct *make_connection(char *service,char *password,
|
||||
int pwlen, char *dev,uint16 vuid, NTSTATUS *status)
|
||||
{
|
||||
@ -327,10 +328,17 @@ connection_struct *make_connection(char *service,char *password,
|
||||
BOOL guest = False;
|
||||
BOOL force = False;
|
||||
connection_struct *conn;
|
||||
uid_t euid;
|
||||
|
||||
fstring user;
|
||||
ZERO_STRUCT(user);
|
||||
|
||||
/* This must ONLY BE CALLED AS ROOT. As it exits this function as root. */
|
||||
if ((euid = geteuid()) != 0) {
|
||||
DEBUG(0,("make_connection: PANIC ERROR. Called as nonroot (%u)\n", (unsigned int)euid ));
|
||||
smb_panic("make_connection: PANIC ERROR. Called as nonroot\n");
|
||||
}
|
||||
|
||||
strlower(service);
|
||||
|
||||
snum = find_service(service);
|
||||
@ -519,7 +527,7 @@ connection_struct *make_connection(char *service,char *password,
|
||||
conn->groups = NULL;
|
||||
|
||||
/* Find all the groups this uid is in and
|
||||
store them. Used by become_user() */
|
||||
store them. Used by change_to_user() */
|
||||
initialise_groups(conn->user, conn->uid, conn->gid);
|
||||
get_current_groups(&conn->ngroups,&conn->groups);
|
||||
|
||||
@ -557,16 +565,7 @@ connection_struct *make_connection(char *service,char *password,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!become_user(conn, conn->vuid)) {
|
||||
/* No point continuing if they fail the basic checks */
|
||||
DEBUG(0,("Can't become connected user!\n"));
|
||||
conn_free(conn);
|
||||
*status = NT_STATUS_LOGON_FAILURE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ROOT Activities: */
|
||||
become_root();
|
||||
/* check number of connections */
|
||||
if (!claim_connection(conn,
|
||||
lp_servicename(SNUM(conn)),
|
||||
@ -575,8 +574,6 @@ connection_struct *make_connection(char *service,char *password,
|
||||
DEBUG(1,("too many connections - rejected\n"));
|
||||
*status = NT_STATUS_INSUFFICIENT_RESOURCES;
|
||||
conn_free(conn);
|
||||
unbecome_root();
|
||||
unbecome_user();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -596,14 +593,19 @@ connection_struct *make_connection(char *service,char *password,
|
||||
lp_max_connections(SNUM(conn)));
|
||||
conn_free(conn);
|
||||
*status = NT_STATUS_UNSUCCESSFUL;
|
||||
unbecome_root();
|
||||
unbecome_user();
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
unbecome_root();
|
||||
|
||||
/* USER Activites: */
|
||||
if (!change_to_user(conn, conn->vuid)) {
|
||||
/* No point continuing if they fail the basic checks */
|
||||
DEBUG(0,("Can't become connected user!\n"));
|
||||
conn_free(conn);
|
||||
*status = NT_STATUS_LOGON_FAILURE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remember that a different vuid can connect later without these checks... */
|
||||
|
||||
/* Preexecs are done here as they might make the dir we are to ChDir to below */
|
||||
@ -616,7 +618,7 @@ connection_struct *make_connection(char *service,char *password,
|
||||
ret = smbrun(cmd,NULL);
|
||||
if (ret != 0 && lp_preexec_close(SNUM(conn))) {
|
||||
DEBUG(1,("preexec gave %d - failing connection\n", ret));
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
yield_connection(conn, lp_servicename(SNUM(conn)), lp_max_connections(SNUM(conn)));
|
||||
conn_free(conn);
|
||||
*status = NT_STATUS_UNSUCCESSFUL;
|
||||
@ -628,7 +630,7 @@ connection_struct *make_connection(char *service,char *password,
|
||||
DEBUG(0,("%s (%s) Can't change directory to %s (%s)\n",
|
||||
remote_machine, conn->client_address,
|
||||
conn->connectpath,strerror(errno)));
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
yield_connection(conn,
|
||||
lp_servicename(SNUM(conn)),
|
||||
lp_max_connections(SNUM(conn)));
|
||||
@ -677,14 +679,14 @@ connection_struct *make_connection(char *service,char *password,
|
||||
if (conn->vfs_ops.connect(conn, service, user) < 0) {
|
||||
DEBUG(0,("make_connection: VFS make connection failed!\n"));
|
||||
*status = NT_STATUS_UNSUCCESSFUL;
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* we've finished with the sensitive stuff */
|
||||
unbecome_user();
|
||||
/* we've finished with the user stuff - go back to root */
|
||||
change_to_root_user();
|
||||
|
||||
return(conn);
|
||||
}
|
||||
@ -697,7 +699,7 @@ void close_cnum(connection_struct *conn, uint16 vuid)
|
||||
{
|
||||
DirCacheFlush(SNUM(conn));
|
||||
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
|
||||
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
|
||||
remote_machine,conn->client_address,
|
||||
@ -720,15 +722,15 @@ void close_cnum(connection_struct *conn, uint16 vuid)
|
||||
|
||||
/* execute any "postexec = " line */
|
||||
if (*lp_postexec(SNUM(conn)) &&
|
||||
become_user(conn, vuid)) {
|
||||
change_to_user(conn, vuid)) {
|
||||
pstring cmd;
|
||||
pstrcpy(cmd,lp_postexec(SNUM(conn)));
|
||||
standard_sub_conn(conn,cmd);
|
||||
smbrun(cmd,NULL);
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
}
|
||||
|
||||
unbecome_user();
|
||||
change_to_root_user();
|
||||
/* execute any "root postexec = " line */
|
||||
if (*lp_rootpostexec(SNUM(conn))) {
|
||||
pstring cmd;
|
||||
|
@ -25,10 +25,10 @@
|
||||
extern struct current_user current_user;
|
||||
|
||||
/****************************************************************************
|
||||
Become the guest user.
|
||||
Become the guest user without changing the security context stack.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL become_guest(void)
|
||||
BOOL change_to_guest(void)
|
||||
{
|
||||
static struct passwd *pass=NULL;
|
||||
static uid_t guest_uid = (uid_t)-1;
|
||||
@ -82,10 +82,11 @@ static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Become the user of a connection number.
|
||||
Become the user of a connection number without changing the security context
|
||||
stack, but modify the currnet_user entries.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
BOOL change_to_user(connection_struct *conn, uint16 vuid)
|
||||
{
|
||||
user_struct *vuser = get_valid_user_struct(vuid);
|
||||
int snum;
|
||||
@ -96,7 +97,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
NT_USER_TOKEN *token = NULL;
|
||||
|
||||
if (!conn) {
|
||||
DEBUG(2,("Connection not open\n"));
|
||||
DEBUG(2,("change_to_user: Connection not open\n"));
|
||||
return(False);
|
||||
}
|
||||
|
||||
@ -109,12 +110,12 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
|
||||
if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
|
||||
(current_user.uid == conn->uid)) {
|
||||
DEBUG(4,("Skipping become_user - already user\n"));
|
||||
DEBUG(4,("change_to_user: Skipping user change - already user\n"));
|
||||
return(True);
|
||||
} else if ((current_user.conn == conn) &&
|
||||
(vuser != 0) && (current_user.vuid == vuid) &&
|
||||
(current_user.uid == vuser->uid)) {
|
||||
DEBUG(4,("Skipping become_user - already user\n"));
|
||||
DEBUG(4,("change_to_user: Skipping user change - already user\n"));
|
||||
return(True);
|
||||
}
|
||||
|
||||
@ -133,7 +134,7 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
token = conn->nt_user_token;
|
||||
} else {
|
||||
if (!vuser) {
|
||||
DEBUG(2,("Invalid vuid used %d\n",vuid));
|
||||
DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid));
|
||||
return(False);
|
||||
}
|
||||
uid = vuser->uid;
|
||||
@ -196,21 +197,22 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
current_user.conn = conn;
|
||||
current_user.vuid = vuid;
|
||||
|
||||
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
|
||||
DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
|
||||
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
|
||||
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Unbecome the user of a connection number.
|
||||
Go back to being root without changing the security context stack,
|
||||
but modify the current_user entries.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL unbecome_user(void )
|
||||
BOOL change_to_root_user(void)
|
||||
{
|
||||
set_root_sec_ctx();
|
||||
|
||||
DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
|
||||
DEBUG(5,("change_to_root_user: now uid=(%d,%d) gid=(%d,%d)\n",
|
||||
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
|
||||
|
||||
current_user.conn = NULL;
|
||||
@ -222,16 +224,13 @@ BOOL unbecome_user(void )
|
||||
/****************************************************************************
|
||||
Become the user of an authenticated connected named pipe.
|
||||
When this is called we are currently running as the connection
|
||||
user.
|
||||
user. Doesn't modify current_user.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL become_authenticated_pipe_user(pipes_struct *p)
|
||||
{
|
||||
BOOL res = push_sec_ctx();
|
||||
|
||||
if (!res) {
|
||||
if (!push_sec_ctx())
|
||||
return False;
|
||||
}
|
||||
|
||||
set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
|
||||
p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token);
|
||||
@ -242,19 +241,93 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
|
||||
/****************************************************************************
|
||||
Unbecome the user of an authenticated connected named pipe.
|
||||
When this is called we are running as the authenticated pipe
|
||||
user and need to go back to being the connection user.
|
||||
user and need to go back to being the connection user. Doesn't modify
|
||||
current_user.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
|
||||
BOOL unbecome_authenticated_pipe_user(void)
|
||||
{
|
||||
return pop_sec_ctx();
|
||||
}
|
||||
|
||||
/* Temporarily become a root user. Must match with unbecome_root(). */
|
||||
/****************************************************************************
|
||||
Utility functions used by become_xxx/unbecome_xxx.
|
||||
****************************************************************************/
|
||||
|
||||
struct conn_ctx {
|
||||
connection_struct *conn;
|
||||
uint16 vuid;
|
||||
};
|
||||
|
||||
/* A stack of current_user connection contexts. */
|
||||
|
||||
static struct conn_ctx conn_ctx_stack[MAX_SEC_CTX_DEPTH];
|
||||
static int conn_ctx_stack_ndx;
|
||||
|
||||
static void push_conn_ctx(void)
|
||||
{
|
||||
struct conn_ctx *ctx_p;
|
||||
|
||||
/* Check we don't overflow our stack */
|
||||
|
||||
if (conn_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
|
||||
DEBUG(0, ("Connection context stack overflow!\n"));
|
||||
smb_panic("Connection context stack overflow!\n");
|
||||
}
|
||||
|
||||
/* Store previous user context */
|
||||
ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
|
||||
|
||||
ctx_p->conn = current_user.conn;
|
||||
ctx_p->vuid = current_user.vuid;
|
||||
|
||||
DEBUG(3, ("push_conn_ctx(%u) : conn_ctx_stack_ndx = %d\n",
|
||||
(unsigned int)ctx_p->vuid, conn_ctx_stack_ndx ));
|
||||
|
||||
conn_ctx_stack_ndx++;
|
||||
}
|
||||
|
||||
static void pop_conn_ctx(void)
|
||||
{
|
||||
struct conn_ctx *ctx_p;
|
||||
|
||||
/* Check for stack underflow. */
|
||||
|
||||
if (conn_ctx_stack_ndx == 0) {
|
||||
DEBUG(0, ("Connection context stack underflow!\n"));
|
||||
smb_panic("Connection context stack underflow!\n");
|
||||
}
|
||||
|
||||
conn_ctx_stack_ndx--;
|
||||
ctx_p = &conn_ctx_stack[conn_ctx_stack_ndx];
|
||||
|
||||
current_user.conn = ctx_p->conn;
|
||||
current_user.vuid = ctx_p->vuid;
|
||||
|
||||
ctx_p->conn = NULL;
|
||||
ctx_p->vuid = UID_FIELD_INVALID;
|
||||
}
|
||||
|
||||
void init_conn_ctx(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Initialise connection context stack */
|
||||
for (i = 0; i < MAX_SEC_CTX_DEPTH; i++) {
|
||||
conn_ctx_stack[i].conn = NULL;
|
||||
conn_ctx_stack[i].vuid = UID_FIELD_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Temporarily become a root user. Must match with unbecome_root(). Saves and
|
||||
restores the connection context.
|
||||
****************************************************************************/
|
||||
|
||||
void become_root(void)
|
||||
{
|
||||
push_sec_ctx();
|
||||
push_conn_ctx();
|
||||
set_root_sec_ctx();
|
||||
}
|
||||
|
||||
@ -263,6 +336,35 @@ void become_root(void)
|
||||
void unbecome_root(void)
|
||||
{
|
||||
pop_sec_ctx();
|
||||
pop_conn_ctx();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Push the current security context then force a change via change_to_user().
|
||||
Saves and restores the connection context.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL become_user(connection_struct *conn, uint16 vuid)
|
||||
{
|
||||
if (!push_sec_ctx())
|
||||
return False;
|
||||
|
||||
push_conn_ctx();
|
||||
|
||||
if (!change_to_user(conn, vuid)) {
|
||||
pop_sec_ctx();
|
||||
pop_conn_ctx();
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
BOOL unbecome_user()
|
||||
{
|
||||
pop_sec_ctx();
|
||||
pop_conn_ctx();
|
||||
return True;
|
||||
}
|
||||
|
||||
/*****************************************************************
|
||||
|
Loading…
x
Reference in New Issue
Block a user