lib/util_seaccess.c

説明を見る。
00001 /*
00002    Unix SMB/CIFS implementation.
00003    Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
00004    Copyright (C) Tim Potter 2000.
00005    Copyright (C) Re-written by Jeremy Allison 2000.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00020 */
00021 
00022 #include "includes.h"
00023 
00024 extern NT_USER_TOKEN anonymous_token;
00025 
00026 /*********************************************************************************
00027  Check an ACE against a SID.  We return the remaining needed permission
00028  bits not yet granted. Zero means permission allowed (no more needed bits).
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          * Inherit only is ignored.
00038          */
00039 
00040         if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
00041                 return acc_desired;
00042         }
00043 
00044         /*
00045          * If this ACE has no SID in common with the token,
00046          * ignore it as it cannot be used to make an access
00047          * determination.
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                          * This is explicitly allowed.
00057                          * Remove the bits from the remaining
00058                          * access required. Return the remaining
00059                          * bits needed.
00060                          */
00061                         acc_desired &= ~mask;
00062                         break;
00063                 case SEC_ACE_TYPE_ACCESS_DENIED:
00064                         /*
00065                          * This is explicitly denied.
00066                          * If any bits match terminate here,
00067                          * we are denied.
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  Maximum access was requested. Calculate the max possible. Fail if it doesn't
00088  include other bits requested.
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          * If we were granted no access, or we desired bits that we
00127          * didn't get, then deny.
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          * Return the access we did get.
00138          */
00139 
00140         *granted = acc_granted;
00141         *status = NT_STATUS_OK;
00142         return True;
00143 }
00144 
00145 /* Map generic access rights to object specific rights.  This technique is
00146    used to give meaning to assigning read, write, execute and all access to
00147    objects.  Each type of object has its own mapping of generic to object
00148    specific access rights. */
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 /* Map standard access rights to object specific rights.  This technique is
00181    used to give meaning to assigning read, write, execute and all access to
00182    objects.  Each type of object has its own mapping of standard to object
00183    specific access rights. */
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  Check access rights of a user against a security descriptor.  Look at
00207  each ACE in the security descriptor until an access denied ACE denies
00208  any of the desired rights to the user or any of the users groups, or one
00209  or more ACEs explicitly grant all requested access rights.  See
00210  "Access-Checking" document in MSDN.
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          * No security descriptor or security descriptor with no DACL
00237          * present allows all access.
00238          */
00239 
00240         /* ACL must have something in it */
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         /* The user sid is the first in the token */
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         /* Is the token the owner of the SID ? */
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                                  * The owner always has SEC_RIGHTS_WRITE_DAC & READ_CONTROL.
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          * If there are no more desired permissions left then
00302          * access was allowed.
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  samr_make_sam_obj_sd
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         /*basic access for every one*/
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         /*full access for builtin aliases Administrators and Account Operators*/
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 }

Sambaに対してSat Aug 29 21:23:00 2009に生成されました。  doxygen 1.4.7