예제 #1
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_flush(khm_handle vcredset)
{
    int i;
    kcdb_credset * cs;

    if(!kcdb_credset_is_credset(vcredset))
        return KHM_ERROR_INVALID_PARAM;

    cs = (kcdb_credset *) vcredset;

    if (kcdb_credset_is_sealed(cs))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(cs->cs));

#ifdef DEBUG
    assert(!(cs->flags & KCDB_CREDSET_FLAG_ENUM));
#endif

    for(i=0;i<cs->nclist;i++) {
        if(cs->clist[i].cred) {
            kcdb_cred_release((khm_handle) cs->clist[i].cred);
        }
    }
    cs->nclist = 0;
    LeaveCriticalSection(&(cs->cs));

    return KHM_ERROR_SUCCESS;
}
예제 #2
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_get_cred(khm_handle vcredset,
		      khm_int32 idx,
		      khm_handle * cred)
{
    kcdb_credset * cs;
    khm_int32 code = KHM_ERROR_SUCCESS;

    if(!kcdb_credset_is_credset(vcredset))
        return KHM_ERROR_INVALID_PARAM;

    cs = (kcdb_credset *) vcredset;

    *cred = NULL;

    EnterCriticalSection(&(cs->cs));
    if(idx < 0 || idx >= cs->nclist)
        code = KHM_ERROR_OUT_OF_BOUNDS;
    else if(!cs->clist[idx].cred || !kcdb_cred_is_active_cred((khm_handle) cs->clist[idx].cred)) {
        code = KHM_ERROR_DELETED;
        if(cs->clist[idx].cred) {
            kcdb_cred_release((khm_handle) cs->clist[idx].cred);
            cs->clist[idx].cred = NULL;
        }
    }
    else {
        kcdb_cred_hold((khm_handle) cs->clist[idx].cred);
        *cred = cs->clist[idx].cred;
    }
    LeaveCriticalSection(&(cs->cs));
    return code;
}
예제 #3
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_delete(khm_handle vcredset)
{
    kcdb_credset * cs;
    int i;

    if(!kcdb_credset_is_credset(vcredset)) {
        return KHM_ERROR_INVALID_PARAM;
    }

    cs = (kcdb_credset *) vcredset;

    EnterCriticalSection(&cs_credset);
    LDELETE(&kcdb_credsets, cs);
    LeaveCriticalSection(&cs_credset);

    EnterCriticalSection(&(cs->cs));
    cs->magic = 0;

    for(i=0;i<cs->nclist;i++) {
        if(cs->clist[i].cred) {
            kcdb_cred_release((khm_handle) cs->clist[i].cred);
        }
    }
    kcdb_credset_buf_delete(cs);

    LeaveCriticalSection(&(cs->cs));
    DeleteCriticalSection(&(cs->cs));

    PFREE(cs);

    return KHM_ERROR_SUCCESS;
}
예제 #4
0
파일: buf.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record)
{
    if(kcdb_cred_is_active_cred(record))
        return kcdb_cred_release(record);
    else if(kcdb_is_active_identity(record))
        return kcdb_identity_release(record);
    else
        return KHM_ERROR_INVALID_PARAM;
}
예제 #5
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_del_cred(khm_handle vcredset,
		      khm_int32 idx)
{
    kcdb_credset * cs;
    khm_int32 code = KHM_ERROR_SUCCESS;

    if(!kcdb_credset_is_credset(vcredset))
        return KHM_ERROR_INVALID_PARAM;

    cs = (kcdb_credset *) vcredset;

    if (kcdb_credset_is_sealed(cs))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(cs->cs));
    if(idx < 0 || idx >= cs->nclist) {
        code = KHM_ERROR_INVALID_PARAM;
        goto _exit;
    }

    if(cs->clist[idx].cred)
        kcdb_cred_release((khm_handle) cs->clist[idx].cred);

    if (!(cs->flags & KCDB_CREDSET_FLAG_ENUM)) {

        if(idx + 1 < cs->nclist)
            memmove(&(cs->clist[idx]), 
                    &(cs->clist[idx+1]), 
                    sizeof(kcdb_credset_credref) * 
                    (cs->nclist - (idx + 1)));

        cs->nclist--;
    } else {
        cs->clist[idx].cred = NULL;
    }

_exit:
    LeaveCriticalSection(&(cs->cs));

    return code;
}
예제 #6
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_find_cred(khm_handle vcredset,
                       khm_handle vcred_src,
                       khm_handle *cred_dest) {
    kcdb_credset * cs;
    khm_handle cred = NULL;
    int idx;

    if (!kcdb_credset_is_credset(vcredset))
        return KHM_ERROR_INVALID_PARAM;

    if (!kcdb_cred_is_active_cred(vcred_src))
        return KHM_ERROR_INVALID_PARAM;

    cs = (kcdb_credset *) vcredset;

    EnterCriticalSection(&cs->cs);
    for (idx = 0; idx < cs->nclist; idx++) {
        if (cs->clist[idx].cred &&
            kcdb_creds_is_equal(vcred_src, cs->clist[idx].cred)) {
            cred = cs->clist[idx].cred;
            break;
        }
    }

    if (cred)
        kcdb_cred_hold(cred);

    LeaveCriticalSection(&cs->cs);

    if (cred) {
        if (cred_dest)
            *cred_dest = cred;
        else
            kcdb_cred_release(cred);

        return KHM_ERROR_SUCCESS;
    } else {
        return KHM_ERROR_NOT_FOUND;
    }
}
예제 #7
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI
kcdb_credset_purge(khm_handle credset)
{
    khm_int32 code = KHM_ERROR_SUCCESS;
    kcdb_credset * cs;
    int i,j;

    if(!kcdb_credset_is_credset(credset))
        return KHM_ERROR_INVALID_PARAM;

    cs = (kcdb_credset *) credset;

    if (kcdb_credset_is_sealed(cs))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(cs->cs));

    /* we can't purge a credset while an enumeration operation is in
       progress. */
    if (cs->flags & KCDB_CREDSET_FLAG_ENUM) {
        code = KHM_ERROR_INVALID_OPERATION;
        goto _exit;
    }

    for(i=0,j=0; i < cs->nclist; i++) {
        if(cs->clist[i].cred) {
            if(!kcdb_cred_is_active_cred((khm_handle) cs->clist[i].cred)) {
                kcdb_cred_release((khm_handle) cs->clist[i].cred);
            } else if(i != j) {
                cs->clist[j++] = cs->clist[i];
            } else
                j++;
        }
    }
    cs->nclist = j;

 _exit:
    LeaveCriticalSection(&(cs->cs));
    return code;
}
예제 #8
0
khm_int32
krb4_msg_newcred(khm_int32 msg_type, khm_int32 msg_subtype,
                 khm_ui_4 uparam, void * vparam) {

    switch(msg_subtype) {
    case KMSG_CRED_NEW_CREDS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct;
            khm_size cbsize;
            wchar_t wbuf[256];

            nc = (khui_new_creds *) vparam;

            nct = PMALLOC(sizeof(*nct));
#ifdef DEBUG
            assert(nct);
#endif
            ZeroMemory(nct, sizeof(*nct));

            nct->type = credtype_id_krb4;
            nct->ordinal = 3;
            LoadString(hResModule, IDS_NC_K4_SHORT,
                       wbuf, ARRAYLENGTH(wbuf));
            StringCbLength(wbuf, sizeof(wbuf), &cbsize);
            cbsize += sizeof(wchar_t);

            nct->name = PMALLOC(cbsize);
            StringCbCopy(nct->name, cbsize, wbuf);

            nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;

            nct->h_module = hResModule;
            nct->dlg_proc = k4_nc_dlg_proc;
            nct->dlg_template = MAKEINTRESOURCE(IDD_NC_KRB4);

            khui_cw_add_type(nc, nct);
        }
        break;

    case KMSG_CRED_RENEW_CREDS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct;
            khm_size cbsize;
            wchar_t wbuf[256];
            khui_action_context * pctx = NULL;

            nc = (khui_new_creds *) vparam;
            pctx = khui_cw_get_ctx(nc);
            if (!pctx->identity)
                break;

            nct = PMALLOC(sizeof(*nct));
#ifdef DEBUG
            assert(nct);
#endif

            ZeroMemory(nct, sizeof(*nct));

            nct->type = credtype_id_krb4;
            nct->ordinal = 3;
            LoadString(hResModule, IDS_NC_K4_SHORT,
                       wbuf, ARRAYLENGTH(wbuf));
            StringCbLength(wbuf, sizeof(wbuf), &cbsize);
            cbsize += sizeof(wchar_t);

            nct->name = PMALLOC(cbsize);
            StringCbCopy(nct->name, cbsize, wbuf);

            nct->type_deps[nct->n_type_deps++] = credtype_id_krb5;

            khui_cw_add_type(nc, nct);
        }
        break;

    case KMSG_CRED_DIALOG_SETUP:
        break;

    case KMSG_CRED_PROCESS:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct = NULL;
            khm_handle ident = NULL;
            khui_action_context * pctx = NULL;
            k4_dlg_data * d = NULL;
            long code = 0;
            wchar_t idname[KCDB_IDENT_MAXCCH_NAME];
            khm_size cb;
            khm_int32 subtype;

            nc = (khui_new_creds *) vparam;
            if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
                break;

            subtype = khui_cw_get_subtype(nc);
            if (subtype == KMSG_CRED_NEW_CREDS ||
                subtype == KMSG_CRED_RENEW_CREDS) {
                khm_int32 method;

                if (subtype == KMSG_CRED_NEW_CREDS) {

                    d = (k4_dlg_data *) nct->aux;

                    if (KHM_FAILED(khui_cw_get_primary_id(nc, &ident)))
                        break;

                    if (!d ||
                        khui_cw_get_result(nc) != KHUI_NC_RESULT_PROCESS) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);
                        kcdb_identity_release(ident);
                        break;
                    }

                    if (!d->k4_enabled) {
                        k4_write_identity_data(d);
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);
                        kcdb_identity_release(ident);
                        break;
                    }

                    method = d->method;

                    cb = sizeof(idname);
                    kcdb_identity_get_name(ident, idname, &cb);
                    _begin_task(0);
                    _report_sr0(KHERR_NONE, IDS_MSG_K4NEW);
                    _resolve();
                    _describe();

                } else if (subtype == KMSG_CRED_RENEW_CREDS) {

                    pctx = khui_cw_get_ctx(nc);

                    if ((pctx->scope == KHUI_SCOPE_IDENT &&
                         pctx->identity != NULL) ||

                        (pctx->scope == KHUI_SCOPE_CREDTYPE &&
                         pctx->cred_type == credtype_id_krb4 &&
                         pctx->identity != NULL) ||

                        (pctx->scope == KHUI_SCOPE_CRED &&
                         pctx->cred_type == credtype_id_krb4 &&
                         pctx->identity != NULL &&
                         pctx->cred != NULL)) {

                        ident = pctx->identity;
                        kcdb_identity_hold(ident);

                        if (!k4_should_identity_get_k4(ident)) {

                            _reportf(L"Kerberos 4 is not enabled for this identity.  Skipping");

                            khui_cw_set_response(nc, credtype_id_krb4,
                                                 KHUI_NC_RESPONSE_FAILED |
                                                 KHUI_NC_RESPONSE_EXIT);
                            kcdb_identity_release(ident);
                            break;
                        }

                    } else {

                        _reportf(L"Kerberos 4 is not within renewal scope. Skipping");

                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_FAILED |
                                             KHUI_NC_RESPONSE_EXIT);
                        break;
                    }

                    method = K4_METHOD_K524; /* only k524 is supported
                                                for renewals */

                    _begin_task(0);
                    cb = sizeof(idname);
                    kcdb_identity_get_name(ident, idname, &cb);
                    _report_sr0(KHERR_NONE, IDS_MSG_K4RENEW);
                    _resolve();
                    _describe();
                } else {
                    assert(FALSE);
                    break;
                }

                _progress(0,1);

                if ((method == K4_METHOD_AUTO ||
                     method == K4_METHOD_K524) &&
                    khui_cw_type_succeeded(nc, credtype_id_krb5)) {

                    khm_handle tgt;
                    FILETIME ft_prev;
                    FILETIME ft_new;
                    khm_size cb;

                    _report_cs0(KHERR_INFO, L"Trying K524...");

                    tgt = khm_krb4_find_tgt(NULL, ident);
                    _progress(1,3);

                    if (tgt) {
                        cb = sizeof(ft_prev);
                        if (KHM_FAILED(kcdb_cred_get_attr(tgt,
                                                          KCDB_ATTR_EXPIRE,
                                                          NULL,
                                                          &ft_prev,
                                                          &cb)))
                            ZeroMemory(&ft_prev, sizeof(ft_prev));
                        kcdb_cred_release(tgt);
                    }

                    code = khm_convert524(ident);
                    _progress(2,3);

                    _reportf(L"khm_convert524 returns code %d", code);

                    if (code == 0) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_SUCCESS |
                                             KHUI_NC_RESPONSE_EXIT);

                        if (subtype == KMSG_CRED_NEW_CREDS) {
                            assert(d != NULL);

                            k4_write_identity_data(d);

                        } else if (subtype == KMSG_CRED_RENEW_CREDS &&
                                   (pctx->scope == KHUI_SCOPE_CREDTYPE ||
                                    pctx->scope == KHUI_SCOPE_CRED)) {

                            khm_krb4_list_tickets();

                            tgt = khm_krb4_find_tgt(NULL, ident);

                            if (tgt) {
                                cb = sizeof(ft_new);
                                ZeroMemory(&ft_new, sizeof(ft_new));

                                kcdb_cred_get_attr(tgt, KCDB_ATTR_EXPIRE,
                                                   NULL, &ft_new, &cb);

                                kcdb_cred_release(tgt);
                            }

                            if (!tgt ||
                                CompareFileTime(&ft_new, &ft_prev) <= 0) {
                                /* The new TGT wasn't much of an
                                   improvement over what we already
                                   had.  We should go out and try to
                                   renew the identity now. */

                                khui_action_context ctx;

                                _reportf(L"Renewal of Krb4 creds failed to get a longer TGT.  Triggering identity renewal");

                                khui_context_create(&ctx,
                                                    KHUI_SCOPE_IDENT,
                                                    pctx->identity,
                                                    KCDB_CREDTYPE_INVALID,
                                                    NULL);
                                khui_action_trigger(KHUI_ACTION_RENEW_CRED,
                                                    &ctx);

                                khui_context_release(&ctx);
                            }
                        }

                        _progress(1,1);

                        _end_task();
                        if (ident)
                            kcdb_identity_release(ident);
                        break;

                    } else if (method == K4_METHOD_K524) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_FAILED |
                                             KHUI_NC_RESPONSE_EXIT);

			if (subtype == KMSG_CRED_RENEW_CREDS &&
			    (pctx->scope == KHUI_SCOPE_CREDTYPE ||
			     pctx->scope == KHUI_SCOPE_CRED)) {
			    /* We were trying to get a new Krb4 TGT
			       for this identity.  Sometimes this
			       fails because of restrictions placed on
			       K524d regarding the lifetime of the
			       issued K4 TGT.  In this case, we
			       trigger a renewal of the identity in
			       the hope that the new K5 TGT will allow
			       us to successfully get a new K4 TGT
			       next time over using the new K5 TGT. */

			    khui_action_context ctx;

                            _reportf(L"Renewal of Krb4 creds failed using k524.  Triggerring identity renewal.");

			    khui_context_create(&ctx,
						KHUI_SCOPE_IDENT,
						pctx->identity,
						KCDB_CREDTYPE_INVALID,
						NULL);

			    khui_action_trigger(KHUI_ACTION_RENEW_CRED,
						&ctx);

			    khui_context_release(&ctx);
			}

                        _progress(1,1);
                        _end_task();

                        if (ident)
                            kcdb_identity_release(ident);
                        break;

                    }
                }

                /* only supported for new credentials */
                if (method == K4_METHOD_AUTO ||
                    method == K4_METHOD_PASSWORD) {

                    khm_size n_prompts = 0;
                    khm_size idx;
                    khm_size cb;
                    wchar_t wpwd[KHUI_MAXCCH_PROMPT_VALUE];
                    char pwd[KHUI_MAXCCH_PROMPT_VALUE];
                    wchar_t widname[KCDB_IDENT_MAXCCH_NAME];
                    char idname[KCDB_IDENT_MAXCCH_NAME];

                    char * aname = NULL;
                    char * inst = NULL;
                    char * realm = NULL;

                    assert(subtype == KMSG_CRED_NEW_CREDS);

                    _report_cs0(KHERR_INFO, L"Trying password ...");

                    code = TRUE; /* just has to be non-zero */

                    khui_cw_get_prompt_count(nc, &n_prompts);

                    if (n_prompts == 0)
                        goto _skip_pwd;

                    for (idx = 0; idx < n_prompts; idx++) {
                        khui_new_creds_prompt * p;

                        if (KHM_FAILED(khui_cw_get_prompt(nc, idx, &p)))
                            continue;

                        if (p->type == KHUI_NCPROMPT_TYPE_PASSWORD)
                            break;
                    }

                    if (idx >= n_prompts) {
                        _reportf(L"Password prompt not found");
                        goto _skip_pwd;
                    }

                    khui_cw_sync_prompt_values(nc);

                    cb = sizeof(wpwd);
                    if (KHM_FAILED(khui_cw_get_prompt_value(nc, idx,
                                                            wpwd,
                                                            &cb))) {
                        _reportf(L"Failed to obtain password value");
                        goto _skip_pwd;
                    }

                    UnicodeStrToAnsi(pwd, sizeof(pwd), wpwd);

                    cb = sizeof(widname);
                    kcdb_identity_get_name(ident,
                                           widname,
                                           &cb);

                    UnicodeStrToAnsi(idname, sizeof(idname), widname);

                    {
                        char * atsign;

                        atsign = strchr(idname, '@');
                        if (atsign == NULL) {
                            _reportf(L"Identity name does not contain an '@'");
                            goto _skip_pwd;
                        }

                        *atsign++ = 0;

                        realm = atsign;
                    }

                    {
                        char * slash;

                        slash = strchr(idname, '/');
                        if (slash != NULL) {
                            *slash++ = 0;
                            inst = slash;
                        } else {
                            inst = "";
                        }
                    }

                    aname = idname;

                    code = khm_krb4_kinit(aname, inst, realm,
                                          (long) d->lifetime, pwd);

                    _progress(2,3);

                    _reportf(L"khm_krb4_kinit returns code %d", code);

                _skip_pwd:

                    if (code) {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_EXIT |
                                             KHUI_NC_RESPONSE_FAILED);

                    } else {
                        khui_cw_set_response(nc, credtype_id_krb4,
                                             KHUI_NC_RESPONSE_EXIT |
                                             KHUI_NC_RESPONSE_SUCCESS);

                        if (subtype == KMSG_CRED_NEW_CREDS) {

                            assert(d != NULL);
                            k4_write_identity_data(d);

                        }
                    }
                }

                _progress(1,1);

                _end_task();
            }

            if (ident)
                kcdb_identity_release(ident);
        }
        break;

    case KMSG_CRED_END:
        {
            khui_new_creds * nc;
            khui_new_creds_by_type * nct = NULL;

            nc = (khui_new_creds *) vparam;
            if (KHM_FAILED(khui_cw_find_type(nc, credtype_id_krb4, &nct)))
                break;

            khui_cw_del_type(nc, credtype_id_krb4);

            if (nct->name)
                PFREE(nct->name);

            if (nct->credtext)
                PFREE(nct->credtext);

            PFREE(nct);
        }
        break;
    }

    return KHM_ERROR_SUCCESS;
}
예제 #9
0
파일: credset.c 프로젝트: aosm/Kerberos
KHMEXP khm_int32 KHMAPI 
kcdb_credset_extract_filtered(khm_handle destcredset,
			      khm_handle sourcecredset,
			      kcdb_cred_filter_func filter,
			      void * rock)
{
    khm_int32 code = KHM_ERROR_SUCCESS;
    kcdb_credset * dest;
    kcdb_credset * src;
    int isRoot = 0;
    khm_size srcSize = 0;
    int i;

    if(!kcdb_credset_is_credset(destcredset))
        return KHM_ERROR_INVALID_PARAM;

    if(sourcecredset) {
        if(!kcdb_credset_is_credset(sourcecredset))
            return KHM_ERROR_INVALID_PARAM;
    } else {
        sourcecredset = kcdb_root_credset;
        isRoot = 1;
    }

    src = (kcdb_credset *) sourcecredset;
    dest = (kcdb_credset *) destcredset;

    if (kcdb_credset_is_sealed(dest))
        return KHM_ERROR_INVALID_OPERATION;

    EnterCriticalSection(&(src->cs));
    EnterCriticalSection(&(dest->cs));

#ifdef DEBUG
    assert(!(dest->flags & KCDB_CREDSET_FLAG_ENUM));
#endif

    if(KHM_FAILED(kcdb_credset_get_size(sourcecredset, &srcSize))) {
        code = KHM_ERROR_UNKNOWN;
        goto _exit;
    }

    kcdb_cred_lock_read();

    dest->flags |= KCDB_CREDSET_FLAG_ENUM;

    for(i=0; i < (int) srcSize; i++) {
        kcdb_cred * c;

        c = src->clist[i].cred;
        if(kcdb_cred_is_active_cred((khm_handle) c) &&
            filter(c, 0, rock))
        {
            if(isRoot) {
                khm_handle newcred;

                kcdb_cred_unlock_read();
                kcdb_cred_dup((khm_handle) c, &newcred);
                kcdb_credset_add_cred(destcredset, newcred, -1);
                kcdb_cred_release(newcred);
                kcdb_cred_lock_read();
            } else {
                kcdb_cred_unlock_read();
                kcdb_credset_add_cred(destcredset, (khm_handle) c, -1);
                kcdb_cred_lock_read();
            }
        }
    }

    dest->flags &= ~KCDB_CREDSET_FLAG_ENUM;

    kcdb_cred_unlock_read();

_exit:
    LeaveCriticalSection(&(dest->cs));
    LeaveCriticalSection(&(src->cs));

    return code;
}
예제 #10
0
파일: credset.c 프로젝트: aosm/Kerberos
/*! \internal

Collect credentials from cs2 to cs1 which have already been selected into
cl1 and cl2.

- Credentials in cl2 that are not in cl1 will get added to cs1
- Credentials in cl1 that are not in cl2 will get removed from cs1
- Credentials in cl1 and cl2 will be updated in cs1

cl1 and cl2 will be modified.
*/
khm_int32 
kcdb_credset_collect_core(kcdb_credset * cs1,
                          kcdb_cred ** cl1,
                          khm_int32 ncl1,
                          kcdb_credset * cs2,
                          kcdb_cred ** cl2,
                          khm_int32 ncl2,
                          khm_int32 * delta)
{
    int i, j;
    int ldelta = 0;
    khm_int32 rv;

    /* find matching creds and update them */
    for(i=0; i<ncl1; i++) 
        if(cl1[i]) {
            for(j=0; j<ncl2; j++) 
                if(cl2[j] && kcdb_creds_is_equal((khm_handle) cl1[i], (khm_handle) cl2[j])) {
                    /* they are equivalent. make them equal */

                    /* depending on whether any changes were made,
                        update ldelta with the proper bit flag */

                    rv = kcdb_cred_update(cl1[i], cl2[j]);
                    if (rv == KHM_ERROR_SUCCESS) {
                        kcdb_credset_update_cred_ref((khm_handle) cs1, (khm_handle) cl1[i]);
                        ldelta |= KCDB_DELTA_MODIFY;
                    }

                    cl2[j] = NULL;
                    cl1[i] = NULL;
                    break;
                }
        }

    /* all the creds that are left in cl1 need to be removed */
    for(i=0; i<ncl1; i++)
        if(cl1[i]) {
            kcdb_credset_del_cred_ref((khm_handle) cs1, (khm_handle) cl1[i]);
            cl1[i] = NULL;
            ldelta |= KCDB_DELTA_DEL;
        }

    /* all the creds in cl2 need to be added to cs1 */
    for(j=0; j<ncl2; j++)
        if(cl2[j]) {
            /* duplicate the credential and add it if we are adding it to the
               root credential store. */
            if(cs1 == kcdb_root_credset) {
                khm_handle h;

                if(KHM_SUCCEEDED(kcdb_cred_dup((khm_handle) cl2[j], &h))) {
                    kcdb_credset_add_cred((khm_handle) cs1, h, -1);
                    kcdb_cred_release(h);
                }
            } else
                kcdb_credset_add_cred((khm_handle) cs1, cl2[j], -1);
            cl2[j] = NULL;
            ldelta |= KCDB_DELTA_ADD;
        }

    if(delta)
        *delta = ldelta;

    if((cs1 == kcdb_root_credset) && ldelta) {
        /* something changed in the root credential set */
        kmq_post_message(KMSG_CRED,KMSG_CRED_ROOTDELTA,ldelta,NULL);
    }
    return KHM_ERROR_SUCCESS;
}
예제 #11
0
/*! \internal

  Collect credentials from cs_src to cs_dest which have already been
  selected into cl_dest and cl_src.

  - Credentials in cl_src that are not in cl_dest will get added to
    cs_dest

  - Credentials in cl_dest that are not in cl_src will get removed
    from cs_dest

  - Credentials in cl_dest and cl_src will be updated in cs_dest

  cl_dest and cl_src will be modified.
*/
khm_int32
kcdb_credset_collect_core(kcdb_credset * cs_dest,
                          kcdb_cred ** cl_dest,
                          khm_int32 ncl_dest,
                          kcdb_credset * cs_src,
                          kcdb_cred ** cl_src,
                          khm_int32 ncl_src,
                          khm_int32 * delta)
{
    int i, j;
    int ldelta = 0;
    khm_int32 rv;
    khm_boolean dest_is_root;
    khm_handle last_identity = NULL;

    dest_is_root = (cs_dest == kcdb_root_credset);

    /* find matching credentials and update them */
    for (i=0; i < ncl_dest; i++) {
        if (cl_dest[i]) {
            for (j=0; j < ncl_src; j++) {
                if (cl_src[j] &&
                    kcdb_creds_is_equal((khm_handle) cl_dest[i], (khm_handle) cl_src[j])) {

                    /* depending on whether any changes were made,
                       update ldelta with the proper bit flag */

                    rv = kcdb_cred_update(cl_dest[i], cl_src[j]);
                    if (rv == KHM_ERROR_SUCCESS) {
                        kcdb_credset_update_cred_ref((khm_handle) cs_dest,
                                                     (khm_handle) cl_dest[i]);
                        ldelta |= KCDB_DELTA_MODIFY;

                        if (dest_is_root)
                            check_and_set_refresh_bit_for_identity(cl_dest[i],
                                                                   &last_identity);
                    }

                    cl_src[j] = NULL;
                    cl_dest[i] = NULL;
                    break;
                }
            }
        }
    }

    /* all the creds that are left in cl_dest need to be removed */
    for (i=0; i < ncl_dest; i++) {
        if (cl_dest[i]) {
            if (dest_is_root)
                check_and_set_refresh_bit_for_identity(cl_dest[i],
                                                       &last_identity);

            kcdb_credset_del_cred_ref((khm_handle) cs_dest, (khm_handle) cl_dest[i]);
            ldelta |= KCDB_DELTA_DEL;

            cl_dest[i] = NULL;
        }
    }

    /* all the creds in cl_src need to be added to cs_dest */
    for (j=0; j < ncl_src; j++) {
        if (cl_src[j]) {
            /* duplicate the credential and add it if we are adding it
               to or from the root credential store. */
            if (cs_dest == kcdb_root_credset ||
                cs_src == kcdb_root_credset) {
                khm_handle h;

                if (KHM_SUCCEEDED(kcdb_cred_dup((khm_handle) cl_src[j], &h))) {
                    kcdb_credset_add_cred((khm_handle) cs_dest, h, -1);
                    kcdb_cred_release(h);
                }
            } else {
                kcdb_credset_add_cred((khm_handle) cs_dest, cl_src[j], -1);
            }

            if (dest_is_root)
                check_and_set_refresh_bit_for_identity(cl_src[j],
                                                       &last_identity);
            cl_src[j] = NULL;
            ldelta |= KCDB_DELTA_ADD;
        }
    }

    if (last_identity) {
        kcdb_identity_release(last_identity);
        last_identity = NULL;
    }

    if (delta)
        *delta = ldelta;

    if (dest_is_root && ldelta) {
        /* something changed in the root credential set */
        kmq_post_message(KMSG_CRED,KMSG_CRED_ROOTDELTA,ldelta,NULL);
    }
    return KHM_ERROR_SUCCESS;
}