summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2000-08-03 22:38:43 +0000
committerJeremy Allison <jra@samba.org>2000-08-03 22:38:43 +0000
commitf87399915b009f88c41cb75a583c2972fe3daf30 (patch)
tree874d5861eba4e7ba655f2d94d6b7a8c1e37bfdfc /source3/smbd
parent468af1937d327cc579dbbdae6e4a9b030998f049 (diff)
downloadsamba-f87399915b009f88c41cb75a583c2972fe3daf30.tar.gz
samba-f87399915b009f88c41cb75a583c2972fe3daf30.tar.bz2
samba-f87399915b009f88c41cb75a583c2972fe3daf30.zip
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 used to be commit e28d01b744b3dbd33e0e54af4e7f426fa8c082b8)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/conn.c5
-rw-r--r--source3/smbd/password.c27
-rw-r--r--source3/smbd/sec_ctx.c98
-rw-r--r--source3/smbd/service.c138
-rw-r--r--source3/smbd/uid.c8
5 files changed, 179 insertions, 97 deletions
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 0e74b62ee0..c1f42be098 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -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)
{
/* Free vfs_connection_struct */
@@ -179,6 +180,7 @@ void conn_free(connection_struct *conn)
if (conn->vfs_conn->groups != NULL) {
free(conn->vfs_conn->groups);
}
+ delete_nt_token(&conn->vfs_conn->nt_user_token);
free(conn->vfs_conn);
}
@@ -190,6 +192,7 @@ void conn_free(connection_struct *conn)
conn->ngroups = 0;
}
+ delete_nt_token(&conn->nt_user_token);
free_namearray(conn->veto_list);
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 0372e7a0f9..9af7d3b1e9 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -113,16 +113,6 @@ user_struct *get_valid_user_struct(uint16 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
****************************************************************************/
void invalidate_vuid(uint16 vuid)
@@ -146,7 +136,6 @@ void invalidate_vuid(uint16 vuid)
delete_nt_token(&vuser->nt_user_token);
}
-
/****************************************************************************
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.
****************************************************************************/
-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;
int i;
+ if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL)
+ return NULL;
+
ZERO_STRUCTP(token);
- if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL)
- return;
+ if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) {
+ free(token);
+ return NULL;
+ }
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++)
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);
/* 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));
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index 432cb223e2..118c2f46b6 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -29,6 +29,7 @@ struct sec_ctx {
uid_t gid;
int ngroups;
gid_t *groups;
+ NT_USER_TOKEN *token;
};
/* 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 int sec_ctx_stack_ndx;
-/* Become the specified uid */
+/****************************************************************************
+ Become the specified uid.
+****************************************************************************/
static BOOL become_uid(uid_t uid)
{
@@ -66,7 +69,9 @@ static BOOL become_uid(uid_t uid)
return True;
}
-/* Become the specified gid */
+/****************************************************************************
+ Become the specified gid.
+****************************************************************************/
static BOOL become_gid(gid_t gid)
{
@@ -91,14 +96,18 @@ static BOOL become_gid(gid_t gid)
return True;
}
-/* Become the specified uid and gid */
+/****************************************************************************
+ Become the specified uid and gid.
+****************************************************************************/
static BOOL become_id(uid_t uid, gid_t gid)
{
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)
{
@@ -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)
{
@@ -158,8 +169,51 @@ int get_current_groups(int *p_ngroups, gid_t **p_groups)
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)
{
@@ -181,11 +235,14 @@ BOOL push_sec_ctx(void)
ctx_p->uid = geteuid();
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);
if (ctx_p->ngroups != 0) {
if (!(ctx_p->groups = malloc(ctx_p->ngroups * sizeof(gid_t)))) {
DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
+ delete_nt_token(&ctx_p->token);
return False;
}
@@ -197,9 +254,11 @@ BOOL push_sec_ctx(void)
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];
@@ -216,8 +275,10 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups)
ctx_p->ngroups = ngroups;
safe_free(ctx_p->groups);
-
+ delete_nt_token(&ctx_p->token);
+
ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
+ ctx_p->token = dup_nt_token(token);
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.ngroups = ngroups;
current_user.groups = groups;
+ current_user.nt_user_token = token;
}
-/* Become root context */
+/****************************************************************************
+ Become root context.
+****************************************************************************/
void set_root_sec_ctx(void)
{
/* 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)
{
@@ -265,6 +331,8 @@ BOOL pop_sec_ctx(void)
safe_free(ctx_p->groups);
ctx_p->ngroups = 0;
+ delete_nt_token(&ctx_p->token);
+
/* Pop back previous user */
sec_ctx_stack_ndx--;
@@ -285,6 +353,7 @@ BOOL pop_sec_ctx(void)
current_user.gid = prev_ctx_p->gid;
current_user.ngroups = prev_ctx_p->ngroups;
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()));
@@ -315,6 +384,8 @@ void init_sec_ctx(void)
get_current_groups(&ctx_p->ngroups, &ctx_p->groups);
+ ctx_p->token = NULL; /* Maps to guest user. */
+
/* Initialise current_user global */
current_user.uid = ctx_p->uid;
@@ -327,4 +398,5 @@ void init_sec_ctx(void)
current_user.conn = NULL;
current_user.vuid = UID_FIELD_INVALID;
+ current_user.nt_user_token = NULL;
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index d4760ca92d..8b63fe6662 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -360,65 +360,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->veto_oplock_list = NULL;
string_set(&conn->dirpath,"");
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
* 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,"",
MAXSTATUS,False);
} /* 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 */
if (*lp_rootpreexec(SNUM(conn))) {
pstring cmd;
@@ -630,13 +639,12 @@ connection_struct *make_connection(char *service,char *user,char *password, int
/* Invoke VFS make connection hook */
- if (conn->vfs_ops.connect) {
- if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) {
- return NULL;
- }
- }
+ if (conn->vfs_ops.connect) {
+ if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0)
+ return NULL;
+ }
- return(conn);
+ return(conn);
}
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 4cb2c512b6..f6687e9a5a 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -47,7 +47,7 @@ BOOL become_guest(void)
initgroups(pass->pw_name, (gid_t)pass->pw_gid);
#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.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.vuid = vuid;
+ current_user.nt_user_token = conn->nt_user_token;
DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
(int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
@@ -206,8 +207,9 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
return False;
}
+ /* JRATEST - this needs fixined w.r.t. NT user tokens... */
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;
}