s3-librpc Remove unused dcesrv_gssapi.[ch] functions
[kai/samba.git] / source3 / rpc_server / srv_access_check.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell                   1992-1997,
5  *  Copyright (C) Luke Kenneth Casson Leighton      1996-1997,
6  *  Copyright (C) Paul Ashton                       1997,
7  *  Copyright (C) Marc Jacobsen                     1999,
8  *  Copyright (C) Jeremy Allison                    2001-2008,
9  *  Copyright (C) Jean François Micouleau           1998-2001,
10  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
11  *  Copyright (C) Gerald (Jerry) Carter             2003-2004,
12  *  Copyright (C) Simo Sorce                        2003.
13  *  Copyright (C) Volker Lendecke                   2005.
14  *  Copyright (C) Guenther Deschner                 2008.
15  *
16  *  This program is free software; you can redistribute it and/or modify
17  *  it under the terms of the GNU General Public License as published by
18  *  the Free Software Foundation; either version 3 of the License, or
19  *  (at your option) any later version.
20  *
21  *  This program is distributed in the hope that it will be useful,
22  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *  GNU General Public License for more details.
25  *
26  *  You should have received a copy of the GNU General Public License
27  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
28  */
29
30 #include "includes.h"
31 #include "system/passwd.h" /* uid_wrapper */
32 #include "rpc_server/srv_access_check.h"
33 #include "../libcli/security/security.h"
34 #include "passdb/machine_sid.h"
35
36 /*******************************************************************
37  Checks if access to an object should be granted, and returns that
38  level of access for further checks.
39
40  If the user has either of needed_priv_1 or needed_priv_2 then they
41  get the rights in rights_mask in addition to any calulated rights.
42
43  This handles the unusual case where we need to allow two different
44  privileges to obtain exactly the same rights, which occours only in
45  SAMR.
46 ********************************************************************/
47
48 NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token,
49                               enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2,
50                               uint32 rights_mask,
51                               uint32 des_access, uint32 *acc_granted,
52                               const char *debug )
53 {
54         NTSTATUS status = NT_STATUS_ACCESS_DENIED;
55         uint32 saved_mask = 0;
56         bool priv_granted = false;
57
58         /* check privileges; certain SAM access bits should be overridden
59            by privileges (mostly having to do with creating/modifying/deleting
60            users and groups) */
61
62         if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) ||
63             (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) {
64                 priv_granted = true;
65                 saved_mask = (des_access & rights_mask);
66                 des_access &= ~saved_mask;
67
68                 DEBUG(4,("access_check_object: user rights access mask [0x%x]\n",
69                         rights_mask));
70         }
71
72
73         /* check the security descriptor first */
74
75         status = se_access_check(psd, token, des_access, acc_granted);
76         if (NT_STATUS_IS_OK(status)) {
77                 goto done;
78         }
79
80         /* give root a free pass */
81
82         if ( geteuid() == sec_initial_uid() ) {
83
84                 DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
85                 DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));
86
87                 priv_granted = true;
88                 *acc_granted = des_access;
89
90                 status = NT_STATUS_OK;
91                 goto done;
92         }
93
94
95 done:
96         if (priv_granted) {
97                 /* add in any bits saved during the privilege check (only
98                    matters if status is ok) */
99
100                 *acc_granted |= rights_mask;
101         }
102
103         DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n",
104                 debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED",
105                 des_access, *acc_granted));
106
107         return status;
108 }
109
110
111 /*******************************************************************
112  Map any MAXIMUM_ALLOWED_ACCESS request to a valid access set.
113 ********************************************************************/
114
115 void map_max_allowed_access(const struct security_token *nt_token,
116                             const struct security_unix_token *unix_token,
117                             uint32_t *pacc_requested)
118 {
119         if (!((*pacc_requested) & MAXIMUM_ALLOWED_ACCESS)) {
120                 return;
121         }
122         *pacc_requested &= ~MAXIMUM_ALLOWED_ACCESS;
123
124         /* At least try for generic read|execute - Everyone gets that. */
125         *pacc_requested = GENERIC_READ_ACCESS|GENERIC_EXECUTE_ACCESS;
126
127         /* root gets anything. */
128         if (unix_token->uid == sec_initial_uid()) {
129                 *pacc_requested |= GENERIC_ALL_ACCESS;
130                 return;
131         }
132
133         /* Full Access for 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
134
135         if (security_token_has_sid(nt_token, &global_sid_Builtin_Administrators) ||
136                         security_token_has_sid(nt_token, &global_sid_Builtin_Account_Operators)) {
137                 *pacc_requested |= GENERIC_ALL_ACCESS;
138                 return;
139         }
140
141         /* Full access for DOMAIN\Domain Admins. */
142         if ( IS_DC ) {
143                 struct dom_sid domadmin_sid;
144                 sid_compose(&domadmin_sid, get_global_sam_sid(),
145                             DOMAIN_RID_ADMINS);
146                 if (security_token_has_sid(nt_token, &domadmin_sid)) {
147                         *pacc_requested |= GENERIC_ALL_ACCESS;
148                         return;
149                 }
150         }
151         /* TODO ! Check privileges. */
152 }