[Freeipa-devel] [PATCH] 0096 support Windows Server 2012

Simo Sorce simo at redhat.com
Wed Dec 5 14:59:30 UTC 2012


On Wed, 2012-12-05 at 14:16 +0200, Alexander Bokovoy wrote:
[..]
> Attached is a prototype to implement logic above. I haven't added
> filtering for anything but our own domain SIDs yet, want to get review
> for this part before going further.

Comments inline.
>  
> +static int dom_sid_cmp(const struct dom_sid *sid1, const struct
> dom_sid *sid2, bool compare_rids)
> +{
> +    int c, num;
> +
> +    if (sid1 == sid2) {
> +        return 0;
> +    }
> +
> +    if (sid1 == NULL) {
> +        return -1;
> +    }
> +
> +    if (sid2 == NULL) {
> +        return 1;
> +    }
> +
> +    /* If SIDs have different revisions, they are different */
> +    if (sid1->sid_rev_num != sid2->sid_rev_num)
> +        return sid1->sid_rev_num - sid2->sid_rev_num;
> +
> +    /* When number of authorities is different, sids are different */
> +    if (sid1->num_auths != sid2->num_auths)
> +        return sid1->num_auths - sid2->num_auths;
> +
> +    /* Optionally skip RIDs if asked */
> +    num = sid1->num_auths - 1;
> +    if (!compare_rids) {
> +        num--;
> +        if (num < 0) return sid1->sub_auths[0] - sid2->sub_auths[0];
> +    }

I a not sure this works if you pass in a domain SID and an actual user
SID, because they are of different lengths. A Domain SID is just like a
USER SID but misses the last authority which represents the RID.

Ie:

Domain SID: S-1-5-21-12345-6789-101123
User SID:   S-1-5-21-12345-6789-101123-501

I think the above function will make comparisons between domain SID and
User SID (which is the only comparison we care about) never succeed.

> +    /* for same size authorities compare them backwards
> +     * since RIDs are likely different */
> +    for (c = num; c >= 0; --c)
> +        if (sid1->sub_auths[c] != sid2->sub_auths[c])
> +            return sid1->sub_auths[c] - sid2->sub_auths[c];
> +
> +    /* Finally, compare Identifier authorities */
> +    for (c = 0; c < SID_ID_AUTHS; c++)
> +        if (sid1->id_auth[c] != sid2->id_auth[c])
> +            return sid1->id_auth[c] - sid2->id_auth[c];

I am wondering, wouldn't it be more efficient if we did a simple
memcmp() here ?
After all these are arrays and should be fully packed.

Also by testing backwards returning the classic -1, 0, +1 makes little
sense because you do not know if a higher authority was 'bigger' or
'smaller' but you found a difference already in a following one.

I would just return true or false from this function, either they match
or they don't. By returning -1,0,1 you mislead the reader in believing
this function might be used in a sorting algorithm, when it cannot as
is.

> +    return 0;
> +}
> +
>  static int sid_append_rid(struct dom_sid *sid, uint32_t rid)
>  {
>      if (sid->num_auths >= SID_SUB_AUTHS) {
> @@ -1070,8 +1118,9 @@ static krb5_error_code
> filter_logon_info(krb5_context context,
>       * attempt at getting us to sign fake credentials with the help
> of a
>       * compromised trusted realm */
>  
> +    struct ipadb_context *ipactx;
>      struct ipadb_adtrusts *domain;
> -    char *domsid;
> +    int i, j, result, count;
>  
>      domain = get_domain_from_realm_update(context, realm);
>      if (!domain) {
> @@ -1089,27 +1138,48 @@ static krb5_error_code
> filter_logon_info(krb5_context context,
>          return EINVAL;
>      }
>  
> -    /* check sid */
> -    domsid = dom_sid_string(NULL, info->info->info3.base.domain_sid);
> -    if (!domsid) {
> -        return EINVAL;
> -    }

I think you can keep the above for reporting debugging purposes later so
you do not have to change the log message.

> -    if (strcmp(domsid, domain->domain_sid) != 0) {
> +    /* check exact sid */
> +    result = dom_sid_cmp(&domain->domsid,
> info->info->info3.base.domain_sid, true);
> +    if (result != 0) {
>          krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
> -                                  "expected domain SID = %s, "
> -                                  "found domain SID = %s",
> -                                  domain->domain_name,
> domain->domain_sid,
> -                                  domsid);
> -        talloc_free(domsid);
> +                                  "expected domain SID = %s, ",
> +                                  domain->domain_name,
> domain->domain_sid);
>          return EINVAL;
>      }
> -    talloc_free(domsid);
>  
> -    /* According to MS-KILE, info->info->info3.sids must be zero, so
> check
> -     * that it is the case here */
> +    /* According to MS-KILE 25.0, info->info->info3.sids may be non
> zero, so check
> +     * should include different possibilities into account
> +     * */
>      if (info->info->info3.sidcount != 0) {
> -        return EINVAL;
> +        ipactx = ipadb_get_context(context);
> +        if (!ipactx && !ipactx->mspac) {
> +            return KRB5_KDB_DBNOTINITED;
> +        }
> +        count = info->info->info3.sidcount;
> +        i = 0;
> +        j = 0;
> +        do {
> +            /* Compare SIDs without taking RID into account */
> +            result = dom_sid_cmp(&ipactx->mspac->domsid,
> info->info->info3.sids[i].sid, false);
> +            if (result == 0) {
> +                krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain
> = %s, "
> +                     "extra sid should be not from the domain %s but
> received RID %d ",
> +                     domain->domain_name,
> ipactx->mspac->flat_domain_name,
> +
> info->info->info3.sids[i].sid->sub_auths[info->info->info3.sids[i].sid->num_auths-1]);
> +                j++;
> +                memmove(info->info->info3.sids+i,
> info->info->info3.sids+i+1, count-i-1);
> +            }

Sorry but doesn't 0 means it's a match ? Looks to me using true/false is
also less confusing.
Also the log message would use a bit of rework, I suggest: "PAC
Filtering issue: sid [%s] is not allowed from a trusted source and will
be excluded." Before this you do a sid to string, this is ok even if
slow as this is an important error condition and should not be common.

> 
The rest and the approach looks otherwise good to me.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York




More information about the Freeipa-devel mailing list