mirror of
https://github.com/samba-team/samba.git
synced 2025-12-02 00:23:50 +03:00
Added an NT_USER_TOKEN structure that is copied/passed around associated
with the current user. This will allow se_access_check() to quickly do a SD check without having to translate uid/gid's to SIDs. Still needs work on pipe calls. Jeremy.
This commit is contained in:
@@ -3546,7 +3546,6 @@ void invalidate_vuid(uint16 vuid);
|
|||||||
char *validated_username(uint16 vuid);
|
char *validated_username(uint16 vuid);
|
||||||
char *validated_domain(uint16 vuid);
|
char *validated_domain(uint16 vuid);
|
||||||
int initialize_groups(char *user, uid_t uid, gid_t gid);
|
int initialize_groups(char *user, uid_t uid, gid_t gid);
|
||||||
void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups);
|
|
||||||
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
|
uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
|
||||||
char *domain,BOOL guest);
|
char *domain,BOOL guest);
|
||||||
void add_session_user(char *user);
|
void add_session_user(char *user);
|
||||||
@@ -3673,8 +3672,9 @@ int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
|
|||||||
/*The following definitions come from smbd/sec_ctx.c */
|
/*The following definitions come from smbd/sec_ctx.c */
|
||||||
|
|
||||||
int get_current_groups(int *p_ngroups, gid_t **p_groups);
|
int get_current_groups(int *p_ngroups, gid_t **p_groups);
|
||||||
|
void delete_nt_token(NT_USER_TOKEN **pptoken);
|
||||||
BOOL push_sec_ctx(void);
|
BOOL push_sec_ctx(void);
|
||||||
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups);
|
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token);
|
||||||
void set_root_sec_ctx(void);
|
void set_root_sec_ctx(void);
|
||||||
BOOL pop_sec_ctx(void);
|
BOOL pop_sec_ctx(void);
|
||||||
void init_sec_ctx(void);
|
void init_sec_ctx(void);
|
||||||
|
|||||||
@@ -383,8 +383,11 @@ struct use_info
|
|||||||
char *domain;
|
char *domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef MAXSUBAUTHS
|
||||||
#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
|
#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _DOM_SID
|
||||||
/* DOM_SID - security id */
|
/* DOM_SID - security id */
|
||||||
typedef struct sid_info
|
typedef struct sid_info
|
||||||
{
|
{
|
||||||
@@ -398,16 +401,21 @@ typedef struct sid_info
|
|||||||
uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
|
uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
|
||||||
|
|
||||||
} DOM_SID;
|
} DOM_SID;
|
||||||
|
#define _DOM_SID
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The complete list of SIDS belonging to this user.
|
* The complete list of SIDS belonging to this user.
|
||||||
* Created when a vuid is registered.
|
* Created when a vuid is registered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _NT_USER_TOKEN
|
||||||
typedef struct _nt_user_token {
|
typedef struct _nt_user_token {
|
||||||
size_t num_sids;
|
size_t num_sids;
|
||||||
DOM_SID *user_sids;
|
DOM_SID *user_sids;
|
||||||
} NT_USER_TOKEN;
|
} NT_USER_TOKEN;
|
||||||
|
#define _NT_USER_TOKEN
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** query a local group, get a list of these: shows who is in that group ***/
|
/*** query a local group, get a list of these: shows who is in that group ***/
|
||||||
|
|
||||||
@@ -580,6 +588,7 @@ typedef struct connection_struct
|
|||||||
/* This groups info is valid for the user that *opened* the connection */
|
/* This groups info is valid for the user that *opened* the connection */
|
||||||
int ngroups;
|
int ngroups;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
NT_USER_TOKEN *nt_user_token;
|
||||||
|
|
||||||
time_t lastused;
|
time_t lastused;
|
||||||
BOOL used;
|
BOOL used;
|
||||||
@@ -598,6 +607,7 @@ struct current_user
|
|||||||
gid_t gid;
|
gid_t gid;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
NT_USER_TOKEN *nt_user_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1672,7 +1682,7 @@ typedef struct
|
|||||||
int n_groups;
|
int n_groups;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
|
||||||
NT_USER_TOKEN nt_user_token;
|
NT_USER_TOKEN *nt_user_token;
|
||||||
|
|
||||||
/* per-user authentication information on NT RPCs */
|
/* per-user authentication information on NT RPCs */
|
||||||
/* lkclXXXX - THIS SHOULD NOT BE HERE! */
|
/* lkclXXXX - THIS SHOULD NOT BE HERE! */
|
||||||
|
|||||||
@@ -64,6 +64,54 @@ typedef char fstring[FSTRING_LEN];
|
|||||||
#define SMB_BIG_UINT unsigned long
|
#define SMB_BIG_UINT unsigned long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXSUBAUTHS
|
||||||
|
#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef uint8
|
||||||
|
#define uint8 unsigned char
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(uint32) && !defined(HAVE_UINT32_FROM_RPC_RPC_H)
|
||||||
|
#if (SIZEOF_INT == 4)
|
||||||
|
#define uint32 unsigned int
|
||||||
|
#elif (SIZEOF_LONG == 4)
|
||||||
|
#define uint32 unsigned long
|
||||||
|
#elif (SIZEOF_SHORT == 4)
|
||||||
|
#define uint32 unsigned short
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _DOM_SID
|
||||||
|
/* DOM_SID - security id */
|
||||||
|
typedef struct sid_info
|
||||||
|
{
|
||||||
|
uint8 sid_rev_num; /* SID revision number */
|
||||||
|
uint8 num_auths; /* number of sub-authorities */
|
||||||
|
uint8 id_auth[6]; /* Identifier Authority */
|
||||||
|
/*
|
||||||
|
* Note that the values in these uint32's are in *native* byteorder,
|
||||||
|
* not neccessarily little-endian...... JRA.
|
||||||
|
*/
|
||||||
|
uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
|
||||||
|
|
||||||
|
} DOM_SID;
|
||||||
|
#define _DOM_SID
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The complete list of SIDS belonging to this user.
|
||||||
|
* Created when a vuid is registered.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NT_USER_TOKEN
|
||||||
|
typedef struct _nt_user_token {
|
||||||
|
size_t num_sids;
|
||||||
|
DOM_SID *user_sids;
|
||||||
|
} NT_USER_TOKEN;
|
||||||
|
#define _NT_USER_TOKEN
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Information from the connection_struct passed to the vfs layer */
|
/* Information from the connection_struct passed to the vfs layer */
|
||||||
|
|
||||||
struct vfs_connection_struct {
|
struct vfs_connection_struct {
|
||||||
@@ -93,6 +141,7 @@ struct vfs_connection_struct {
|
|||||||
gid_t gid;
|
gid_t gid;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
NT_USER_TOKEN *nt_user_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Avoid conflict with an AIX include file */
|
/* Avoid conflict with an AIX include file */
|
||||||
|
|||||||
@@ -33,13 +33,14 @@ extern fstring global_myworkgroup;
|
|||||||
* Some useful sids
|
* Some useful sids
|
||||||
*/
|
*/
|
||||||
|
|
||||||
DOM_SID global_sid_S_1_5_0x20; /* local well-known domain */
|
DOM_SID global_sid_Builtin; /* local well-known domain */
|
||||||
DOM_SID global_sid_World_Domain; /* everyone */
|
DOM_SID global_sid_World_Domain; /* everyone */
|
||||||
DOM_SID global_sid_World; /* everyone */
|
DOM_SID global_sid_World; /* everyone */
|
||||||
DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner */
|
DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner */
|
||||||
DOM_SID global_sid_Creator_Owner; /* Creator Owner */
|
DOM_SID global_sid_Creator_Owner; /* Creator Owner */
|
||||||
DOM_SID global_sid_NT_Authority; /* NT Authority */
|
DOM_SID global_sid_NT_Authority; /* NT Authority */
|
||||||
DOM_SID global_sid_NULL; /* NULL sid */
|
DOM_SID global_sid_NULL; /* NULL sid */
|
||||||
|
DOM_SID global_sid_Builtin_Guests;
|
||||||
|
|
||||||
const DOM_SID *global_sid_everyone = &global_sid_World;
|
const DOM_SID *global_sid_everyone = &global_sid_World;
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ sid_name_map[] =
|
|||||||
{
|
{
|
||||||
{ &global_sam_sid, global_myname, NULL},
|
{ &global_sam_sid, global_myname, NULL},
|
||||||
{ &global_sam_sid, global_myworkgroup, NULL},
|
{ &global_sam_sid, global_myworkgroup, NULL},
|
||||||
{ &global_sid_S_1_5_0x20, "BUILTIN", NULL},
|
{ &global_sid_Builtin, "BUILTIN", NULL},
|
||||||
{ &global_sid_World_Domain, "", &everyone_users[0] },
|
{ &global_sid_World_Domain, "", &everyone_users[0] },
|
||||||
{ &global_sid_Creator_Owner_Domain, "", &creator_owner_users[0] },
|
{ &global_sid_Creator_Owner_Domain, "", &creator_owner_users[0] },
|
||||||
{ &global_sid_NT_Authority, "NT Authority", &nt_authority_users[0] },
|
{ &global_sid_NT_Authority, "NT Authority", &nt_authority_users[0] },
|
||||||
@@ -88,7 +89,8 @@ sid_name_map[] =
|
|||||||
|
|
||||||
void generate_wellknown_sids(void)
|
void generate_wellknown_sids(void)
|
||||||
{
|
{
|
||||||
string_to_sid(&global_sid_S_1_5_0x20, "S-1-5-32");
|
string_to_sid(&global_sid_Builtin, "S-1-5-32");
|
||||||
|
string_to_sid(&global_sid_Builtin_Guests, "S-1-5-32-546");
|
||||||
string_to_sid(&global_sid_World_Domain, "S-1-1");
|
string_to_sid(&global_sid_World_Domain, "S-1-1");
|
||||||
string_to_sid(&global_sid_World, "S-1-1-0");
|
string_to_sid(&global_sid_World, "S-1-1-0");
|
||||||
string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
|
string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
|
||||||
|
|||||||
@@ -162,8 +162,9 @@ BOOL conn_idle_all(time_t t, int deadtime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
free a conn structure
|
Free a conn structure.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void conn_free(connection_struct *conn)
|
void conn_free(connection_struct *conn)
|
||||||
{
|
{
|
||||||
/* Free vfs_connection_struct */
|
/* Free vfs_connection_struct */
|
||||||
@@ -179,6 +180,7 @@ void conn_free(connection_struct *conn)
|
|||||||
if (conn->vfs_conn->groups != NULL) {
|
if (conn->vfs_conn->groups != NULL) {
|
||||||
free(conn->vfs_conn->groups);
|
free(conn->vfs_conn->groups);
|
||||||
}
|
}
|
||||||
|
delete_nt_token(&conn->vfs_conn->nt_user_token);
|
||||||
free(conn->vfs_conn);
|
free(conn->vfs_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +192,7 @@ void conn_free(connection_struct *conn)
|
|||||||
conn->ngroups = 0;
|
conn->ngroups = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_nt_token(&conn->nt_user_token);
|
||||||
free_namearray(conn->veto_list);
|
free_namearray(conn->veto_list);
|
||||||
free_namearray(conn->hide_list);
|
free_namearray(conn->hide_list);
|
||||||
free_namearray(conn->veto_oplock_list);
|
free_namearray(conn->veto_oplock_list);
|
||||||
|
|||||||
@@ -112,16 +112,6 @@ user_struct *get_valid_user_struct(uint16 vuid)
|
|||||||
return &validated_users[vuid];
|
return &validated_users[vuid];
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
Delete the SID list for this user.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static void delete_nt_token(NT_USER_TOKEN *token)
|
|
||||||
{
|
|
||||||
safe_free( token->user_sids );
|
|
||||||
ZERO_STRUCTP(token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
invalidate a uid
|
invalidate a uid
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -146,7 +136,6 @@ void invalidate_vuid(uint16 vuid)
|
|||||||
delete_nt_token(&vuser->nt_user_token);
|
delete_nt_token(&vuser->nt_user_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
return a validated username
|
return a validated username
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -192,15 +181,21 @@ int initialize_groups(char *user, uid_t uid, gid_t gid)
|
|||||||
Create the SID list for this user.
|
Create the SID list for this user.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups)
|
NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
|
||||||
{
|
{
|
||||||
|
NT_USER_TOKEN *token;
|
||||||
DOM_SID *psids;
|
DOM_SID *psids;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
ZERO_STRUCTP(token);
|
ZERO_STRUCTP(token);
|
||||||
|
|
||||||
if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
|
if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) {
|
||||||
return;
|
free(token);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
psids = token->user_sids;
|
psids = token->user_sids;
|
||||||
|
|
||||||
@@ -211,6 +206,8 @@ void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid
|
|||||||
|
|
||||||
for (i = 0; i < ngroups; i++)
|
for (i = 0; i < ngroups; i++)
|
||||||
gid_to_sid( &psids[i+2], groups[i]);
|
gid_to_sid( &psids[i+2], groups[i]);
|
||||||
|
|
||||||
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -258,7 +255,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name,
|
|||||||
get_current_groups( &vuser->n_groups, &vuser->groups);
|
get_current_groups( &vuser->n_groups, &vuser->groups);
|
||||||
|
|
||||||
/* Create an NT_USER_TOKEN struct for this user. */
|
/* Create an NT_USER_TOKEN struct for this user. */
|
||||||
setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups);
|
vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups);
|
||||||
|
|
||||||
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
|
DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct sec_ctx {
|
|||||||
uid_t gid;
|
uid_t gid;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
gid_t *groups;
|
gid_t *groups;
|
||||||
|
NT_USER_TOKEN *token;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A stack of security contexts. We include the current context as being
|
/* A stack of security contexts. We include the current context as being
|
||||||
@@ -37,7 +38,9 @@ struct sec_ctx {
|
|||||||
static struct sec_ctx sec_ctx_stack[MAX_SEC_CTX_DEPTH + 1];
|
static struct sec_ctx sec_ctx_stack[MAX_SEC_CTX_DEPTH + 1];
|
||||||
static int sec_ctx_stack_ndx;
|
static int sec_ctx_stack_ndx;
|
||||||
|
|
||||||
/* Become the specified uid */
|
/****************************************************************************
|
||||||
|
Become the specified uid.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL become_uid(uid_t uid)
|
static BOOL become_uid(uid_t uid)
|
||||||
{
|
{
|
||||||
@@ -66,7 +69,9 @@ static BOOL become_uid(uid_t uid)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Become the specified gid */
|
/****************************************************************************
|
||||||
|
Become the specified gid.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL become_gid(gid_t gid)
|
static BOOL become_gid(gid_t gid)
|
||||||
{
|
{
|
||||||
@@ -91,14 +96,18 @@ static BOOL become_gid(gid_t gid)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Become the specified uid and gid */
|
/****************************************************************************
|
||||||
|
Become the specified uid and gid.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
static BOOL become_id(uid_t uid, gid_t gid)
|
static BOOL become_id(uid_t uid, gid_t gid)
|
||||||
{
|
{
|
||||||
return become_gid(gid) && become_uid(uid);
|
return become_gid(gid) && become_uid(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Drop back to root privileges in order to change to another user */
|
/****************************************************************************
|
||||||
|
Drop back to root privileges in order to change to another user.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
static void gain_root(void)
|
static void gain_root(void)
|
||||||
{
|
{
|
||||||
@@ -123,7 +132,9 @@ static void gain_root(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the list of current groups */
|
/****************************************************************************
|
||||||
|
Get the list of current groups.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
int get_current_groups(int *p_ngroups, gid_t **p_groups)
|
int get_current_groups(int *p_ngroups, gid_t **p_groups)
|
||||||
{
|
{
|
||||||
@@ -158,8 +169,51 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups)
|
|||||||
return ngroups;
|
return ngroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new security context on the stack. It is the same as the old
|
/****************************************************************************
|
||||||
one. User changes are done using the set_sec_ctx() function. */
|
Delete a SID token.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
void delete_nt_token(NT_USER_TOKEN **pptoken)
|
||||||
|
{
|
||||||
|
if (*pptoken) {
|
||||||
|
NT_USER_TOKEN *ptoken = *pptoken;
|
||||||
|
safe_free( ptoken->user_sids );
|
||||||
|
ZERO_STRUCTP(ptoken);
|
||||||
|
}
|
||||||
|
safe_free(*pptoken);
|
||||||
|
*pptoken = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Duplicate a SID token.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
|
||||||
|
{
|
||||||
|
NT_USER_TOKEN *token;
|
||||||
|
|
||||||
|
if (!ptoken)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ZERO_STRUCTP(token);
|
||||||
|
|
||||||
|
if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) {
|
||||||
|
free(token);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
token->num_sids = ptoken->num_sids;
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Create a new security context on the stack. It is the same as the old
|
||||||
|
one. User changes are done using the set_sec_ctx() function.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL push_sec_ctx(void)
|
BOOL push_sec_ctx(void)
|
||||||
{
|
{
|
||||||
@@ -181,11 +235,14 @@ BOOL push_sec_ctx(void)
|
|||||||
ctx_p->uid = geteuid();
|
ctx_p->uid = geteuid();
|
||||||
ctx_p->gid = getegid();
|
ctx_p->gid = getegid();
|
||||||
|
|
||||||
|
ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token);
|
||||||
|
|
||||||
ctx_p->ngroups = sys_getgroups(0, NULL);
|
ctx_p->ngroups = sys_getgroups(0, NULL);
|
||||||
|
|
||||||
if (ctx_p->ngroups != 0) {
|
if (ctx_p->ngroups != 0) {
|
||||||
if (!(ctx_p->groups = malloc(ctx_p->ngroups * sizeof(gid_t)))) {
|
if (!(ctx_p->groups = malloc(ctx_p->ngroups * sizeof(gid_t)))) {
|
||||||
DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
|
DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
|
||||||
|
delete_nt_token(&ctx_p->token);
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +254,11 @@ BOOL push_sec_ctx(void)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the current security context to a given user */
|
/****************************************************************************
|
||||||
|
Set the current security context to a given user.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
|
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
|
||||||
{
|
{
|
||||||
struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
|
struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
|
||||||
|
|
||||||
@@ -216,8 +275,10 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
|
|||||||
ctx_p->ngroups = ngroups;
|
ctx_p->ngroups = ngroups;
|
||||||
|
|
||||||
safe_free(ctx_p->groups);
|
safe_free(ctx_p->groups);
|
||||||
|
delete_nt_token(&ctx_p->token);
|
||||||
|
|
||||||
ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
|
ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
|
||||||
|
ctx_p->token = dup_nt_token(token);
|
||||||
|
|
||||||
become_id(uid, gid);
|
become_id(uid, gid);
|
||||||
|
|
||||||
@@ -230,18 +291,23 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
|
|||||||
current_user.gid = gid;
|
current_user.gid = gid;
|
||||||
current_user.ngroups = ngroups;
|
current_user.ngroups = ngroups;
|
||||||
current_user.groups = groups;
|
current_user.groups = groups;
|
||||||
|
current_user.nt_user_token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Become root context */
|
/****************************************************************************
|
||||||
|
Become root context.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
void set_root_sec_ctx(void)
|
void set_root_sec_ctx(void)
|
||||||
{
|
{
|
||||||
/* May need to worry about supplementary groups at some stage */
|
/* May need to worry about supplementary groups at some stage */
|
||||||
|
|
||||||
set_sec_ctx(0, 0, 0, NULL);
|
set_sec_ctx(0, 0, 0, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop a security context from the stack */
|
/****************************************************************************
|
||||||
|
Pop a security context from the stack.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL pop_sec_ctx(void)
|
BOOL pop_sec_ctx(void)
|
||||||
{
|
{
|
||||||
@@ -265,6 +331,8 @@ BOOL pop_sec_ctx(void)
|
|||||||
safe_free(ctx_p->groups);
|
safe_free(ctx_p->groups);
|
||||||
ctx_p->ngroups = 0;
|
ctx_p->ngroups = 0;
|
||||||
|
|
||||||
|
delete_nt_token(&ctx_p->token);
|
||||||
|
|
||||||
/* Pop back previous user */
|
/* Pop back previous user */
|
||||||
|
|
||||||
sec_ctx_stack_ndx--;
|
sec_ctx_stack_ndx--;
|
||||||
@@ -285,6 +353,7 @@ BOOL pop_sec_ctx(void)
|
|||||||
current_user.gid = prev_ctx_p->gid;
|
current_user.gid = prev_ctx_p->gid;
|
||||||
current_user.ngroups = prev_ctx_p->ngroups;
|
current_user.ngroups = prev_ctx_p->ngroups;
|
||||||
current_user.groups = prev_ctx_p->groups;
|
current_user.groups = prev_ctx_p->groups;
|
||||||
|
current_user.nt_user_token = prev_ctx_p->token;
|
||||||
|
|
||||||
DEBUG(3, ("popped off to sec ctx (%d, %d)\n", geteuid(), getegid()));
|
DEBUG(3, ("popped off to sec ctx (%d, %d)\n", geteuid(), getegid()));
|
||||||
|
|
||||||
@@ -315,6 +384,8 @@ void init_sec_ctx(void)
|
|||||||
|
|
||||||
get_current_groups(&ctx_p->ngroups, &ctx_p->groups);
|
get_current_groups(&ctx_p->ngroups, &ctx_p->groups);
|
||||||
|
|
||||||
|
ctx_p->token = NULL; /* Maps to guest user. */
|
||||||
|
|
||||||
/* Initialise current_user global */
|
/* Initialise current_user global */
|
||||||
|
|
||||||
current_user.uid = ctx_p->uid;
|
current_user.uid = ctx_p->uid;
|
||||||
@@ -327,4 +398,5 @@ void init_sec_ctx(void)
|
|||||||
|
|
||||||
current_user.conn = NULL;
|
current_user.conn = NULL;
|
||||||
current_user.vuid = UID_FIELD_INVALID;
|
current_user.vuid = UID_FIELD_INVALID;
|
||||||
|
current_user.nt_user_token = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -360,65 +360,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
|
|||||||
conn->veto_oplock_list = NULL;
|
conn->veto_oplock_list = NULL;
|
||||||
string_set(&conn->dirpath,"");
|
string_set(&conn->dirpath,"");
|
||||||
string_set(&conn->user,user);
|
string_set(&conn->user,user);
|
||||||
|
conn->nt_user_token = NULL;
|
||||||
|
|
||||||
conn->vfs_conn = (struct vfs_connection_struct *)
|
|
||||||
malloc(sizeof(struct vfs_connection_struct));
|
|
||||||
|
|
||||||
if (conn->vfs_conn == NULL) {
|
|
||||||
DEBUG(0, ("No memory to create vfs_connection_struct"));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZERO_STRUCTP(conn->vfs_conn);
|
|
||||||
|
|
||||||
/* Copy across relevant data from connection struct */
|
|
||||||
|
|
||||||
conn->vfs_conn->printer = conn->printer;
|
|
||||||
conn->vfs_conn->ipc = conn->ipc;
|
|
||||||
conn->vfs_conn->read_only = conn->read_only;
|
|
||||||
conn->vfs_conn->admin_user = conn->admin_user;
|
|
||||||
|
|
||||||
pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
|
|
||||||
pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
|
|
||||||
pstrcpy(conn->vfs_conn->origpath, conn->origpath);
|
|
||||||
|
|
||||||
pstrcpy(conn->vfs_conn->service, service);
|
|
||||||
pstrcpy(conn->vfs_conn->user, conn->user);
|
|
||||||
|
|
||||||
conn->vfs_conn->uid = conn->uid;
|
|
||||||
conn->vfs_conn->gid = conn->gid;
|
|
||||||
conn->vfs_conn->ngroups = conn->ngroups;
|
|
||||||
if (conn->vfs_conn->ngroups != 0) {
|
|
||||||
conn->vfs_conn->groups = (gid_t *)memdup(conn->groups,
|
|
||||||
conn->ngroups * sizeof(gid_t));
|
|
||||||
} else {
|
|
||||||
conn->vfs_conn->groups = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialise VFS function pointers */
|
|
||||||
|
|
||||||
if (*lp_vfsobj(SNUM(conn))) {
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBDL
|
|
||||||
|
|
||||||
/* Loadable object file */
|
|
||||||
|
|
||||||
if (!vfs_init_custom(conn)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
DEBUG(0, ("No libdl present - cannot use VFS objects\n"));
|
|
||||||
conn_free(conn);
|
|
||||||
return NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Normal share - initialise with disk access functions */
|
|
||||||
|
|
||||||
vfs_init_default(conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If force user is true, then store the
|
* If force user is true, then store the
|
||||||
* given userid and also the primary groupid
|
* given userid and also the primary groupid
|
||||||
@@ -529,7 +472,73 @@ connection_struct *make_connection(char *service,char *user,char *password, int
|
|||||||
claim_connection(conn,"",
|
claim_connection(conn,"",
|
||||||
MAXSTATUS,False);
|
MAXSTATUS,False);
|
||||||
} /* IS_IPC */
|
} /* IS_IPC */
|
||||||
|
|
||||||
|
conn->nt_user_token = create_nt_token(conn->uid, conn->gid, conn->ngroups, conn->groups);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now initialize the vfs layer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
conn->vfs_conn = (struct vfs_connection_struct *)
|
||||||
|
malloc(sizeof(struct vfs_connection_struct));
|
||||||
|
|
||||||
|
if (conn->vfs_conn == NULL) {
|
||||||
|
DEBUG(0, ("No memory to create vfs_connection_struct"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZERO_STRUCTP(conn->vfs_conn);
|
||||||
|
|
||||||
|
/* Copy across relevant data from connection struct */
|
||||||
|
|
||||||
|
conn->vfs_conn->printer = conn->printer;
|
||||||
|
conn->vfs_conn->ipc = conn->ipc;
|
||||||
|
conn->vfs_conn->read_only = conn->read_only;
|
||||||
|
conn->vfs_conn->admin_user = conn->admin_user;
|
||||||
|
|
||||||
|
pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
|
||||||
|
pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
|
||||||
|
pstrcpy(conn->vfs_conn->origpath, conn->origpath);
|
||||||
|
|
||||||
|
pstrcpy(conn->vfs_conn->service, service);
|
||||||
|
pstrcpy(conn->vfs_conn->user, conn->user);
|
||||||
|
|
||||||
|
conn->vfs_conn->uid = conn->uid;
|
||||||
|
conn->vfs_conn->gid = conn->gid;
|
||||||
|
conn->vfs_conn->ngroups = conn->ngroups;
|
||||||
|
if (conn->vfs_conn->ngroups != 0) {
|
||||||
|
conn->vfs_conn->groups = (gid_t *)memdup(conn->groups,
|
||||||
|
conn->ngroups * sizeof(gid_t));
|
||||||
|
} else {
|
||||||
|
conn->vfs_conn->groups = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
conn->vfs_conn->nt_user_token = dup_nt_token(conn->nt_user_token);
|
||||||
|
|
||||||
|
/* Initialise VFS function pointers */
|
||||||
|
|
||||||
|
if (*lp_vfsobj(SNUM(conn))) {
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBDL
|
||||||
|
|
||||||
|
/* Loadable object file */
|
||||||
|
|
||||||
|
if (!vfs_init_custom(conn)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
DEBUG(0, ("No libdl present - cannot use VFS objects\n"));
|
||||||
|
conn_free(conn);
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Normal share - initialise with disk access functions */
|
||||||
|
|
||||||
|
vfs_init_default(conn);
|
||||||
|
}
|
||||||
|
|
||||||
/* execute any "root preexec = " line */
|
/* execute any "root preexec = " line */
|
||||||
if (*lp_rootpreexec(SNUM(conn))) {
|
if (*lp_rootpreexec(SNUM(conn))) {
|
||||||
pstring cmd;
|
pstring cmd;
|
||||||
@@ -630,13 +639,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int
|
|||||||
|
|
||||||
/* Invoke VFS make connection hook */
|
/* Invoke VFS make connection hook */
|
||||||
|
|
||||||
if (conn->vfs_ops.connect) {
|
if (conn->vfs_ops.connect) {
|
||||||
if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) {
|
if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return(conn);
|
return(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ BOOL become_guest(void)
|
|||||||
initgroups(pass->pw_name, (gid_t)pass->pw_gid);
|
initgroups(pass->pw_name, (gid_t)pass->pw_gid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL);
|
set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
|
||||||
|
|
||||||
current_user.conn = NULL;
|
current_user.conn = NULL;
|
||||||
current_user.vuid = UID_FIELD_INVALID;
|
current_user.vuid = UID_FIELD_INVALID;
|
||||||
@@ -164,10 +164,11 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups);
|
set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, current_user.nt_user_token);
|
||||||
|
|
||||||
current_user.conn = conn;
|
current_user.conn = conn;
|
||||||
current_user.vuid = vuid;
|
current_user.vuid = vuid;
|
||||||
|
current_user.nt_user_token = conn->nt_user_token;
|
||||||
|
|
||||||
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
|
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
|
||||||
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
|
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
|
||||||
@@ -206,8 +207,9 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* JRATEST - this needs fixined w.r.t. NT user tokens... */
|
||||||
set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
|
set_sec_ctx(p->pipe_user.uid, p->pipe_user.gid,
|
||||||
p->pipe_user.ngroups, p->pipe_user.groups);
|
p->pipe_user.ngroups, p->pipe_user.groups, NULL);
|
||||||
|
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user