summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/chgpasswd.c2
-rw-r--r--source3/smbd/conn.c8
-rw-r--r--source3/smbd/password.c6
-rw-r--r--source3/smbd/sec_ctx.c27
-rw-r--r--source3/smbd/service.c4
-rw-r--r--source3/smbd/uid.c18
6 files changed, 56 insertions, 9 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index e3df8a11d0..8e4df1a464 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -991,7 +991,7 @@ NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passw
if (!push_sec_ctx())
return NT_STATUS_UNSUCCESSFUL;
- set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
+ set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL, NULL);
set_re_uid();
}
diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c
index 9bac0acdb9..0805f8e690 100644
--- a/source3/smbd/conn.c
+++ b/source3/smbd/conn.c
@@ -249,6 +249,14 @@ void conn_free(connection_struct *conn)
conn->ngroups = 0;
}
+ if (conn->nt_user_token) {
+ delete_nt_token(&(conn->nt_user_token));
+ }
+
+ if (conn->privs) {
+ destroy_privilege(&(conn->privs));
+ }
+
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 10c6aadb1f..8438f2a593 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -87,6 +87,7 @@ void invalidate_vuid(uint16 vuid)
SAFE_FREE(vuser->groups);
delete_nt_token(&vuser->nt_user_token);
+ destroy_privilege(&vuser->privs);
SAFE_FREE(vuser);
num_validated_vuids--;
}
@@ -234,6 +235,11 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key,
return UID_FIELD_INVALID;
}
+ if (server_info->privs) {
+ init_privilege(&(vuser->privs));
+ dup_priv_set(vuser->privs, server_info->privs);
+ }
+
/* use this to keep tabs on all our info from the authentication */
vuser->server_info = server_info;
diff --git a/source3/smbd/sec_ctx.c b/source3/smbd/sec_ctx.c
index 8a85792ead..9244f34394 100644
--- a/source3/smbd/sec_ctx.c
+++ b/source3/smbd/sec_ctx.c
@@ -28,6 +28,7 @@ struct sec_ctx {
int ngroups;
gid_t *groups;
NT_USER_TOKEN *token;
+ PRIVILEGE_SET *privs;
};
/* A stack of security contexts. We include the current context as being
@@ -256,6 +257,10 @@ BOOL push_sec_ctx(void)
(unsigned int)ctx_p->uid, (unsigned int)ctx_p->gid, sec_ctx_stack_ndx ));
ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token);
+ if (! ctx_p->token) {
+ DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
+ return False;
+ }
ctx_p->ngroups = sys_getgroups(0, NULL);
@@ -271,6 +276,14 @@ BOOL push_sec_ctx(void)
ctx_p->groups = NULL;
}
+ init_privilege(&ctx_p->privs);
+ if (! NT_STATUS_IS_OK(dup_priv_set(ctx_p->privs, sec_ctx_stack[sec_ctx_stack_ndx-1].privs))) {
+ DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
+ delete_nt_token(&ctx_p->token);
+ destroy_privilege(&ctx_p->privs);
+ return False;
+ }
+
return True;
}
@@ -278,7 +291,7 @@ BOOL push_sec_ctx(void)
Set the current security context to a given user.
****************************************************************************/
-void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
+void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token, PRIVILEGE_SET *privs)
{
struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
@@ -303,9 +316,14 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
smb_panic("DUPLICATE_TOKEN");
delete_nt_token(&ctx_p->token);
+ if (ctx_p->privs)
+ reset_privilege(ctx_p->privs);
+ else
+ init_privilege(&ctx_p->privs);
ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
ctx_p->token = dup_nt_token(token);
+ dup_priv_set(ctx_p->privs, privs);
become_id(uid, gid);
@@ -319,6 +337,7 @@ void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN
current_user.ngroups = ngroups;
current_user.groups = groups;
current_user.nt_user_token = ctx_p->token;
+ current_user.privs = ctx_p->privs;
}
/****************************************************************************
@@ -329,7 +348,7 @@ void set_root_sec_ctx(void)
{
/* May need to worry about supplementary groups at some stage */
- set_sec_ctx(0, 0, 0, NULL, NULL);
+ set_sec_ctx(0, 0, 0, NULL, NULL, NULL);
}
/****************************************************************************
@@ -359,6 +378,7 @@ BOOL pop_sec_ctx(void)
ctx_p->ngroups = 0;
delete_nt_token(&ctx_p->token);
+ destroy_privilege(&ctx_p->privs);
/* Pop back previous user */
@@ -381,6 +401,7 @@ BOOL pop_sec_ctx(void)
current_user.ngroups = prev_ctx_p->ngroups;
current_user.groups = prev_ctx_p->groups;
current_user.nt_user_token = prev_ctx_p->token;
+ current_user.privs = prev_ctx_p->privs;
DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
(unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx));
@@ -413,6 +434,7 @@ void init_sec_ctx(void)
get_current_groups(ctx_p->gid, &ctx_p->ngroups, &ctx_p->groups);
ctx_p->token = NULL; /* Maps to guest user. */
+ ctx_p->privs = NULL;
/* Initialise current_user global */
@@ -427,4 +449,5 @@ void init_sec_ctx(void)
current_user.conn = NULL;
current_user.vuid = UID_FIELD_INVALID;
current_user.nt_user_token = NULL;
+ current_user.privs = NULL;
}
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 78b610ae37..caa2872f04 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -371,6 +371,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
string_set(&conn->dirpath,"");
string_set(&conn->user,user);
conn->nt_user_token = NULL;
+ conn->privs = NULL;
conn->read_only = lp_readonly(conn->service);
conn->admin_user = False;
@@ -479,6 +480,9 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
conn->nt_user_token = create_nt_token(conn->uid, conn->gid,
conn->ngroups, conn->groups,
guest);
+
+ init_privilege(&(conn->privs));
+ pdb_get_privilege_set(conn->nt_user_token, conn->privs);
}
/*
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 3859298055..d43bf301e8 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -44,7 +44,7 @@ BOOL change_to_guest(void)
initgroups(pass->pw_name, pass->pw_gid);
#endif
- set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL);
+ set_sec_ctx(pass->pw_uid, pass->pw_gid, 0, NULL, NULL, NULL);
current_user.conn = NULL;
current_user.vuid = UID_FIELD_INVALID;
@@ -161,8 +161,9 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
gid_t gid;
uid_t uid;
char group_c;
- BOOL must_free_token = False;
+ BOOL must_free_token_priv = False;
NT_USER_TOKEN *token = NULL;
+ PRIVILEGE_SET *privs = NULL;
if (!conn) {
DEBUG(2,("change_to_user: Connection not open\n"));
@@ -195,12 +196,14 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
current_user.groups = conn->groups;
current_user.ngroups = conn->ngroups;
token = conn->nt_user_token;
+ privs = conn->privs;
} else if ((vuser) && check_user_ok(conn, vuser, snum)) {
uid = conn->admin_user ? 0 : vuser->uid;
gid = vuser->gid;
current_user.ngroups = vuser->n_groups;
current_user.groups = vuser->groups;
token = vuser->nt_user_token;
+ privs = vuser->privs;
} else {
DEBUG(2,("change_to_user: Invalid vuid used %d or vuid not permitted access to share.\n",vuid));
return False;
@@ -248,17 +251,20 @@ BOOL change_to_user(connection_struct *conn, uint16 vuid)
DEBUG(1, ("change_to_user: create_nt_token failed!\n"));
return False;
}
- must_free_token = True;
+ pdb_get_privilege_set(token, privs);
+ must_free_token_priv = True;
}
- set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token);
+ set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token, privs);
/*
* Free the new token (as set_sec_ctx copies it).
*/
- if (must_free_token)
+ if (must_free_token_priv) {
delete_nt_token(&token);
+ destroy_privilege(&privs);
+ }
current_user.conn = conn;
current_user.vuid = vuid;
@@ -299,7 +305,7 @@ BOOL become_authenticated_pipe_user(pipes_struct *p)
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);
+ p->pipe_user.ngroups, p->pipe_user.groups, p->pipe_user.nt_user_token, p->pipe_user.privs);
return True;
}