diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/chgpasswd.c | 2 | ||||
-rw-r--r-- | source3/smbd/conn.c | 8 | ||||
-rw-r--r-- | source3/smbd/password.c | 6 | ||||
-rw-r--r-- | source3/smbd/sec_ctx.c | 27 | ||||
-rw-r--r-- | source3/smbd/service.c | 4 | ||||
-rw-r--r-- | source3/smbd/uid.c | 18 |
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; } |