00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 extern NT_USER_TOKEN anonymous_token;
00025
00026
00027
00028
00029
00030
00031 static uint32 check_ace(SEC_ACE *ace, const NT_USER_TOKEN *token, uint32 acc_desired,
00032 NTSTATUS *status)
00033 {
00034 uint32 mask = ace->access_mask;
00035
00036
00037
00038
00039
00040 if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
00041 return acc_desired;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050 if (!token_sid_in_ace( token, ace))
00051 return acc_desired;
00052
00053 switch (ace->type) {
00054 case SEC_ACE_TYPE_ACCESS_ALLOWED:
00055
00056
00057
00058
00059
00060
00061 acc_desired &= ~mask;
00062 break;
00063 case SEC_ACE_TYPE_ACCESS_DENIED:
00064
00065
00066
00067
00068
00069 if (acc_desired & mask) {
00070 *status = NT_STATUS_ACCESS_DENIED;
00071 return 0xFFFFFFFF;
00072 }
00073 break;
00074 case SEC_ACE_TYPE_SYSTEM_ALARM:
00075 case SEC_ACE_TYPE_SYSTEM_AUDIT:
00076 *status = NT_STATUS_NOT_IMPLEMENTED;
00077 return 0xFFFFFFFF;
00078 default:
00079 *status = NT_STATUS_INVALID_PARAMETER;
00080 return 0xFFFFFFFF;
00081 }
00082
00083 return acc_desired;
00084 }
00085
00086
00087
00088
00089
00090
00091 static BOOL get_max_access( SEC_ACL *the_acl, const NT_USER_TOKEN *token, uint32 *granted,
00092 uint32 desired,
00093 NTSTATUS *status)
00094 {
00095 uint32 acc_denied = 0;
00096 uint32 acc_granted = 0;
00097 size_t i;
00098
00099 for ( i = 0 ; i < the_acl->num_aces; i++) {
00100 SEC_ACE *ace = &the_acl->aces[i];
00101 uint32 mask = ace->access_mask;
00102
00103 if (!token_sid_in_ace( token, ace))
00104 continue;
00105
00106 switch (ace->type) {
00107 case SEC_ACE_TYPE_ACCESS_ALLOWED:
00108 acc_granted |= (mask & ~acc_denied);
00109 break;
00110 case SEC_ACE_TYPE_ACCESS_DENIED:
00111 acc_denied |= (mask & ~acc_granted);
00112 break;
00113 case SEC_ACE_TYPE_SYSTEM_ALARM:
00114 case SEC_ACE_TYPE_SYSTEM_AUDIT:
00115 *status = NT_STATUS_NOT_IMPLEMENTED;
00116 *granted = 0;
00117 return False;
00118 default:
00119 *status = NT_STATUS_INVALID_PARAMETER;
00120 *granted = 0;
00121 return False;
00122 }
00123 }
00124
00125
00126
00127
00128
00129
00130 if ((acc_granted == 0) || ((acc_granted & desired) != desired)) {
00131 *status = NT_STATUS_ACCESS_DENIED;
00132 *granted = 0;
00133 return False;
00134 }
00135
00136
00137
00138
00139
00140 *granted = acc_granted;
00141 *status = NT_STATUS_OK;
00142 return True;
00143 }
00144
00145
00146
00147
00148
00149
00150 void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
00151 {
00152 uint32 old_mask = *access_mask;
00153
00154 if (*access_mask & GENERIC_READ_ACCESS) {
00155 *access_mask &= ~GENERIC_READ_ACCESS;
00156 *access_mask |= mapping->generic_read;
00157 }
00158
00159 if (*access_mask & GENERIC_WRITE_ACCESS) {
00160 *access_mask &= ~GENERIC_WRITE_ACCESS;
00161 *access_mask |= mapping->generic_write;
00162 }
00163
00164 if (*access_mask & GENERIC_EXECUTE_ACCESS) {
00165 *access_mask &= ~GENERIC_EXECUTE_ACCESS;
00166 *access_mask |= mapping->generic_execute;
00167 }
00168
00169 if (*access_mask & GENERIC_ALL_ACCESS) {
00170 *access_mask &= ~GENERIC_ALL_ACCESS;
00171 *access_mask |= mapping->generic_all;
00172 }
00173
00174 if (old_mask != *access_mask) {
00175 DEBUG(10, ("se_map_generic(): mapped mask 0x%08x to 0x%08x\n",
00176 old_mask, *access_mask));
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185 void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
00186 {
00187 uint32 old_mask = *access_mask;
00188
00189 if (*access_mask & READ_CONTROL_ACCESS) {
00190 *access_mask &= ~READ_CONTROL_ACCESS;
00191 *access_mask |= mapping->std_read;
00192 }
00193
00194 if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) {
00195 *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
00196 *access_mask |= mapping->std_all;
00197 }
00198
00199 if (old_mask != *access_mask) {
00200 DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
00201 old_mask, *access_mask));
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 BOOL se_access_check(const SEC_DESC *sd, const NT_USER_TOKEN *token,
00214 uint32 acc_desired, uint32 *acc_granted,
00215 NTSTATUS *status)
00216 {
00217 size_t i;
00218 SEC_ACL *the_acl;
00219 fstring sid_str;
00220 uint32 tmp_acc_desired = acc_desired;
00221
00222 if (!status || !acc_granted)
00223 return False;
00224
00225 if (!token)
00226 token = &anonymous_token;
00227
00228 *status = NT_STATUS_OK;
00229 *acc_granted = 0;
00230
00231 DEBUG(10,("se_access_check: requested access 0x%08x, for NT token with %u entries and first sid %s.\n",
00232 (unsigned int)acc_desired, (unsigned int)token->num_sids,
00233 sid_to_string(sid_str, &token->user_sids[0])));
00234
00235
00236
00237
00238
00239
00240
00241
00242 if (!sd || (sd && (!(sd->type & SEC_DESC_DACL_PRESENT) || sd->dacl == NULL))) {
00243 *status = NT_STATUS_OK;
00244 *acc_granted = acc_desired;
00245 DEBUG(5, ("se_access_check: no sd or blank DACL, access allowed\n"));
00246 return True;
00247 }
00248
00249
00250 if (DEBUGLVL(3)) {
00251 DEBUG(3, ("se_access_check: user sid is %s\n", sid_to_string(sid_str, &token->user_sids[PRIMARY_USER_SID_INDEX]) ));
00252
00253 for (i = 1; i < token->num_sids; i++) {
00254 DEBUGADD(3, ("se_access_check: also %s\n",
00255 sid_to_string(sid_str, &token->user_sids[i])));
00256 }
00257 }
00258
00259
00260
00261 if (sd->owner_sid) {
00262 for (i = 0; i < token->num_sids; i++) {
00263 if (sid_equal(&token->user_sids[i], sd->owner_sid)) {
00264
00265
00266
00267 if (tmp_acc_desired & WRITE_DAC_ACCESS)
00268 tmp_acc_desired &= ~WRITE_DAC_ACCESS;
00269 if (tmp_acc_desired & READ_CONTROL_ACCESS)
00270 tmp_acc_desired &= ~READ_CONTROL_ACCESS;
00271 }
00272 }
00273 }
00274
00275 the_acl = sd->dacl;
00276
00277 if (tmp_acc_desired & MAXIMUM_ALLOWED_ACCESS) {
00278 tmp_acc_desired &= ~MAXIMUM_ALLOWED_ACCESS;
00279 return get_max_access( the_acl, token, acc_granted, tmp_acc_desired,
00280 status);
00281 }
00282
00283 for ( i = 0 ; i < the_acl->num_aces && tmp_acc_desired != 0; i++) {
00284 SEC_ACE *ace = &the_acl->aces[i];
00285
00286 DEBUGADD(10,("se_access_check: ACE %u: type %d, flags = 0x%02x, SID = %s mask = %x, current desired = %x\n",
00287 (unsigned int)i, ace->type, ace->flags,
00288 sid_to_string(sid_str, &ace->trustee),
00289 (unsigned int) ace->access_mask,
00290 (unsigned int)tmp_acc_desired ));
00291
00292 tmp_acc_desired = check_ace( ace, token, tmp_acc_desired, status);
00293 if (NT_STATUS_V(*status)) {
00294 *acc_granted = 0;
00295 DEBUG(5,("se_access_check: ACE %u denied with status %s.\n", (unsigned int)i, nt_errstr(*status)));
00296 return False;
00297 }
00298 }
00299
00300
00301
00302
00303
00304
00305 if (tmp_acc_desired == 0) {
00306 *acc_granted = acc_desired;
00307 *status = NT_STATUS_OK;
00308 DEBUG(5,("se_access_check: access (%x) granted.\n", (unsigned int)acc_desired ));
00309 return True;
00310 }
00311
00312 *acc_granted = 0;
00313 *status = NT_STATUS_ACCESS_DENIED;
00314 DEBUG(5,("se_access_check: access (%x) denied.\n", (unsigned int)acc_desired ));
00315 return False;
00316 }
00317
00318
00319
00320
00321
00322
00323 NTSTATUS samr_make_sam_obj_sd(TALLOC_CTX *ctx, SEC_DESC **psd, size_t *sd_size)
00324 {
00325 DOM_SID adm_sid;
00326 DOM_SID act_sid;
00327
00328 SEC_ACE ace[3];
00329 SEC_ACCESS mask;
00330
00331 SEC_ACL *psa = NULL;
00332
00333 sid_copy(&adm_sid, &global_sid_Builtin);
00334 sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
00335
00336 sid_copy(&act_sid, &global_sid_Builtin);
00337 sid_append_rid(&act_sid, BUILTIN_ALIAS_RID_ACCOUNT_OPS);
00338
00339
00340 init_sec_access(&mask, GENERIC_RIGHTS_SAM_EXECUTE | GENERIC_RIGHTS_SAM_READ);
00341 init_sec_ace(&ace[0], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00342
00343
00344 init_sec_access(&mask, GENERIC_RIGHTS_SAM_ALL_ACCESS);
00345 init_sec_ace(&ace[1], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00346 init_sec_ace(&ace[2], &act_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, mask, 0);
00347
00348 if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 3, ace)) == NULL)
00349 return NT_STATUS_NO_MEMORY;
00350
00351 if ((*psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, sd_size)) == NULL)
00352 return NT_STATUS_NO_MEMORY;
00353
00354 return NT_STATUS_OK;
00355 }