#include<kcreddbinternal.h>
#include<assert.h>
CRITICAL_SECTION cs_creds;
kcdb_cred * kcdb_creds = NULL;
RWLOCK l_creds;
khm_ui_8 kcdb_cred_id = 0;
void kcdb_cred_init(void)
{
InitializeCriticalSection(&cs_creds);
InitializeRwLock(&l_creds);
kcdb_cred_id = 0;
}
void kcdb_cred_exit(void)
{
DeleteCriticalSection(&cs_creds);
DeleteRwLock(&l_creds);
}
KHMEXP khm_int32 KHMAPI
kcdb_cred_create(const wchar_t * name,
khm_handle identity,
khm_int32 cred_type,
khm_handle * result)
{
kcdb_cred * cred;
size_t cb_name;
if(!name || !result ||
FAILED(StringCbLength(name, KCDB_CRED_MAXCB_NAME, &cb_name)) ||
KHM_FAILED(kcdb_credtype_get_info(cred_type, NULL)) ||
KHM_FAILED(kcdb_identity_hold(identity))) {
return KHM_ERROR_INVALID_PARAM;
}
cb_name += sizeof(wchar_t);
cred = PMALLOC(sizeof(kcdb_cred));
ZeroMemory(cred, sizeof(kcdb_cred));
cred->magic = KCDB_CRED_MAGIC;
cred->identity = identity;
cred->name = PMALLOC(cb_name);
StringCbCopy(cred->name, cb_name, name);
cred->type = cred_type;
cred->refcount = 1;
LINIT(cred);
kcdb_buf_new(&cred->buf, KCDB_ATTR_MAX_ID + 1);
EnterCriticalSection(&cs_creds);
cred->id = kcdb_cred_id++;
LPUSH(&kcdb_creds, cred);
LeaveCriticalSection(&cs_creds);
*result = cred;
return KHM_ERROR_SUCCESS;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_update(khm_handle vdest,
khm_handle vsrc)
{
khm_int32 rv = KHM_ERROR_EQUIVALENT;
kcdb_cred * src;
kcdb_cred * dest;
kcdb_type * t;
kcdb_attrib * a;
void * srcbuf;
void * destbuf;
khm_size cbsrcbuf;
khm_size cbdestbuf;
int i;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vsrc) ||
!kcdb_cred_is_active_cred(vdest))
goto _exit;
src = (kcdb_cred *) vsrc;
dest = (kcdb_cred *) vdest;
for(i=0;i<KCDB_ATTR_MAX_ID;i++) {
if(kcdb_cred_val_exist(src, i)) {
if(KHM_FAILED(kcdb_attrib_get_info(i, &a)))
continue;
if((a->flags & KCDB_ATTR_FLAG_COMPUTED) ||
KHM_FAILED(kcdb_type_get_info(a->type, &t))) {
kcdb_attrib_release_info(a);
continue;
}
srcbuf = kcdb_cred_buf_get(src,i);
cbsrcbuf = kcdb_cred_buf_size(src, i);
if(kcdb_cred_val_exist(dest, i)) {
destbuf = kcdb_cred_buf_get(dest, i);
cbdestbuf = kcdb_cred_buf_size(dest, i);
if(!t->comp(srcbuf, cbsrcbuf, destbuf, cbdestbuf))
goto _skip_copy;
}
kcdb_buf_set_value(&dest->buf, i, (khm_ui_2) i, srcbuf, cbsrcbuf);
rv = KHM_ERROR_SUCCESS;
_skip_copy:
kcdb_attrib_release_info(a);
kcdb_type_release_info(t);
} else {
if (KHM_FAILED(kcdb_attrib_get_info(i, &a)))
continue;
if (!(a->flags & KCDB_ATTR_FLAG_COMPUTED) &&
(a->flags & KCDB_ATTR_FLAG_TRANSIENT) &&
kcdb_cred_val_exist(dest, i)) {
kcdb_buf_set_value(&dest->buf, i, (khm_ui_2) i, NULL, 0);
rv = KHM_ERROR_SUCCESS;
}
kcdb_attrib_release_info(a);
}
}
if (dest->flags != src->flags) {
khm_int32 old_flags;
old_flags = dest->flags;
dest->flags = (src->flags & ~KCDB_CRED_FLAGMASK_ADDITIVE) |
((src->flags | dest->flags) & KCDB_CRED_FLAGMASK_ADDITIVE);
if (dest->flags != old_flags)
rv = KHM_ERROR_SUCCESS;
}
_exit:
kcdb_cred_unlock_write();
return rv;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_dup(
khm_handle vcred,
khm_handle * pnewcred)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
kcdb_cred * newcred;
khm_handle vnewcred;
if(!pnewcred)
return KHM_ERROR_INVALID_PARAM;
*pnewcred = NULL;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
if(KHM_FAILED(kcdb_cred_create(cred->name,
cred->identity,
cred->type,
&vnewcred)))
{
code = KHM_ERROR_UNKNOWN;
goto _exit;
}
newcred = (kcdb_cred *) vnewcred;
newcred->flags = cred->flags;
kcdb_buf_dup(&newcred->buf, &cred->buf);
*pnewcred = (khm_handle) newcred;
_exit:
kcdb_cred_unlock_write();
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_serial(
khm_handle vcred,
khm_ui_8 * pserial)
{
kcdb_cred * c;
if(!pserial)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
kcdb_cred_unlock_read();
return KHM_ERROR_INVALID_PARAM;
}
c = (kcdb_cred *) vcred;
*pserial = c->id;
kcdb_cred_unlock_read();
return KHM_ERROR_SUCCESS;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_set_identity(
khm_handle vcred,
khm_handle id)
{
kcdb_cred * c;
if(!kcdb_is_identity(id))
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vcred)) {
kcdb_cred_unlock_write();
return KHM_ERROR_INVALID_PARAM;
}
c = (kcdb_cred *) vcred;
if(c->identity) {
kcdb_identity_release((khm_handle) c->identity);
}
kcdb_identity_hold(id);
c->identity = (kcdb_identity *) id;
kcdb_cred_unlock_write();
return KHM_ERROR_SUCCESS;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_type(
khm_handle vcred,
khm_int32 * type)
{
kcdb_cred * c;
if(!type)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
kcdb_cred_unlock_read();
return KHM_ERROR_INVALID_PARAM;
}
c = (kcdb_cred *) vcred;
*type = c->type;
kcdb_cred_unlock_read();
return KHM_ERROR_SUCCESS;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_set_attrib(
khm_handle cred,
const wchar_t * name,
void * buffer,
khm_size cbbuf)
{
khm_int32 attr_id = -1;
if(KHM_FAILED(kcdb_attrib_get_id(name, &attr_id)))
return KHM_ERROR_INVALID_PARAM;
return kcdb_cred_set_attr(
cred,
attr_id,
buffer,
cbbuf);
}
KHMEXP khm_int32 KHMAPI kcdb_cred_set_attr(
khm_handle vcred,
khm_int32 attr_id,
void * buffer,
khm_size cbbuf)
{
kcdb_cred * cred;
kcdb_type * type = NULL;
kcdb_attrib * attrib = NULL;
khm_size cbdest;
khm_int32 code = KHM_ERROR_SUCCESS;
if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vcred)) {
kcdb_cred_unlock_write();
return KHM_ERROR_INVALID_PARAM;
}
cred = (kcdb_cred *) vcred;
if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) {
kcdb_cred_unlock_write();
return KHM_ERROR_INVALID_PARAM;
}
if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED)
{
kcdb_cred_unlock_write();
kcdb_attrib_release_info(attrib);
return KHM_ERROR_INVALID_OPERATION;
}
if (buffer == 0) {
kcdb_buf_alloc(&cred->buf, attr_id, (khm_ui_2) attr_id, 0);
code = KHM_ERROR_SUCCESS;
goto _exit;
}
if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) {
kcdb_cred_unlock_write();
kcdb_attrib_release_info(attrib);
return KHM_ERROR_INVALID_PARAM;
}
if(!(type->isValid(buffer,cbbuf))) {
code = KHM_ERROR_TYPE_MISMATCH;
goto _exit;
}
if((type->dup(buffer, cbbuf, NULL, &cbdest)) != KHM_ERROR_TOO_LONG) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
kcdb_buf_alloc(&cred->buf, attr_id, (khm_ui_2) attr_id, cbdest);
if(!kcdb_cred_buf_exist(cred, attr_id)) {
code = KHM_ERROR_NO_RESOURCES;
goto _exit;
}
if(KHM_FAILED(code =
type->dup(buffer, cbbuf, kcdb_cred_buf_get(cred,attr_id), &cbdest)))
{
kcdb_buf_alloc(&cred->buf, attr_id, (khm_ui_2) attr_id, 0);
goto _exit;
}
kcdb_buf_set_value_flag(&cred->buf, attr_id);
_exit:
kcdb_cred_unlock_write();
if(attrib)
kcdb_attrib_release_info(attrib);
if(type)
kcdb_type_release_info(type);
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_attrib(
khm_handle cred,
const wchar_t * name,
khm_int32 * attr_type,
void * buffer,
khm_size * cbbuf)
{
khm_int32 attr_id = -1;
if(KHM_FAILED(kcdb_attrib_get_id(name, &attr_id)))
return KHM_ERROR_NOT_FOUND;
return kcdb_cred_get_attr(
cred,
attr_id,
attr_type,
buffer,
cbbuf);
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_attrib_string(
khm_handle cred,
const wchar_t * name,
wchar_t * buffer,
khm_size * cbbuf,
khm_int32 flags)
{
khm_int32 attr_id = -1;
if(KHM_FAILED(kcdb_attrib_get_id(name, &attr_id)))
return KHM_ERROR_NOT_FOUND;
return kcdb_cred_get_attr_string(
cred,
attr_id,
buffer,
cbbuf,
flags);
}
KHMEXP khm_int32 KHMAPI
kcdb_cred_get_attr(khm_handle vcred,
khm_int32 attr_id,
khm_int32 * attr_type,
void * buffer,
khm_size * pcbbuf)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred = NULL;
kcdb_attrib * attrib = NULL;
kcdb_type * type = NULL;
if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID)
return KHM_ERROR_INVALID_PARAM;
if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) {
return KHM_ERROR_INVALID_PARAM;
}
if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) {
kcdb_attrib_release_info(attrib);
return KHM_ERROR_UNKNOWN;
}
if(attr_type)
*attr_type = attrib->type;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
if(!buffer && !pcbbuf) {
code = (kcdb_cred_val_exist(cred, attr_id) ||
(attrib->flags & KCDB_ATTR_FLAG_COMPUTED))?KHM_ERROR_SUCCESS:KHM_ERROR_NOT_FOUND;
goto _exit;
}
if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED) {
code = attrib->compute_cb(
vcred,
attr_id,
buffer,
pcbbuf);
} else if (kcdb_cred_val_exist(cred, attr_id)) {
code = type->dup(
kcdb_cred_buf_get(cred, attr_id),
kcdb_cred_buf_size(cred, attr_id),
buffer,
pcbbuf);
} else {
code = KHM_ERROR_NOT_FOUND;
}
_exit:
kcdb_cred_unlock_read();
if(type)
kcdb_type_release_info(type);
if(attrib)
kcdb_attrib_release_info(attrib);
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_attr_string(
khm_handle vcred,
khm_int32 attr_id,
wchar_t * buffer,
khm_size * pcbbuf,
khm_int32 flags)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred = NULL;
kcdb_attrib * attrib = NULL;
kcdb_type * type = NULL;
if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID)
return KHM_ERROR_INVALID_PARAM;
if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib))) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit_nolock;
}
if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type))) {
code = KHM_ERROR_UNKNOWN;
goto _exit_nolock;
}
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
if(!buffer && !pcbbuf) {
code = (kcdb_cred_val_exist(cred, attr_id) ||
(attrib->flags & KCDB_ATTR_FLAG_COMPUTED))?KHM_ERROR_SUCCESS:KHM_ERROR_NOT_FOUND;
goto _exit;
}
if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED) {
void * buf;
khm_size cbbuf;
code = attrib->compute_cb(vcred,
attr_id,
NULL,
&cbbuf);
if(code == KHM_ERROR_TOO_LONG) {
wchar_t vbuf[KCDB_MAXCCH_NAME];
if (cbbuf < sizeof(vbuf))
buf = vbuf;
else
buf = PMALLOC(cbbuf);
code = attrib->compute_cb(vcred,
attr_id,
buf,
&cbbuf);
if(KHM_SUCCEEDED(code)) {
code = type->toString(buf,
cbbuf,
buffer,
pcbbuf,
flags);
}
if (buf != vbuf)
PFREE(buf);
}
} else {
if(kcdb_cred_buf_exist(cred, attr_id)) {
code = type->toString(
kcdb_cred_buf_get(cred, attr_id),
kcdb_cred_buf_size(cred, attr_id),
buffer,
pcbbuf,
flags);
} else
code = KHM_ERROR_NOT_FOUND;
}
_exit:
kcdb_cred_unlock_read();
_exit_nolock:
if(type)
kcdb_type_release_info(type);
if(attrib)
kcdb_attrib_release_info(attrib);
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_name(
khm_handle vcred,
wchar_t * buffer,
khm_size * cbbuf)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred = NULL;
size_t cbsize;
if(!cbbuf)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
if(FAILED(StringCbLength(cred->name, KCDB_CRED_MAXCB_NAME, &cbsize))) {
code = KHM_ERROR_UNKNOWN;
goto _exit;
}
cbsize += sizeof(wchar_t);
if(!buffer || *cbbuf < cbsize) {
*cbbuf = cbsize;
code = KHM_ERROR_TOO_LONG;
goto _exit;
}
StringCbCopy(buffer, *cbbuf, cred->name);
*cbbuf = cbsize;
_exit:
kcdb_cred_unlock_read();
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_get_identity(
khm_handle vcred,
khm_handle * identity)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
if(!identity)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
kcdb_identity_hold((khm_handle) cred->identity);
*identity = cred->identity;
_exit:
kcdb_cred_unlock_read();
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_hold(khm_handle vcred)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
kcdb_cred_lock_write();
if(!kcdb_cred_is_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
cred->refcount++;
_exit:
kcdb_cred_unlock_write();
return code;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_release(khm_handle vcred)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
kcdb_cred_lock_write();
if(!kcdb_cred_is_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
cred->refcount--;
_exit:
kcdb_cred_unlock_write();
kcdb_cred_check_and_delete(vcred);
return code;
}
void kcdb_cred_check_and_delete(khm_handle vcred)
{
kcdb_cred * cred;
kcdb_cred_lock_read();
if(!kcdb_cred_is_cred(vcred)) {
goto _exit;
}
cred = (kcdb_cred *) vcred;
if(cred->refcount)
goto _exit;
kcdb_cred_unlock_read();
kcdb_cred_lock_write();
if(!kcdb_cred_is_cred(vcred)) {
goto _exit2;
}
cred->magic = 0;
kcdb_identity_release(cred->identity);
EnterCriticalSection(&cs_creds);
LDELETE(&kcdb_creds, cred);
LeaveCriticalSection(&cs_creds);
kcdb_buf_delete(&cred->buf);
PFREE(cred->name);
PFREE(cred);
_exit2:
kcdb_cred_unlock_write();
return;
_exit:
kcdb_cred_unlock_read();
}
KHMEXP khm_int32 KHMAPI kcdb_cred_delete(khm_handle vcred)
{
khm_int32 code = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vcred)) {
code = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = (kcdb_cred *) vcred;
cred->flags |= KCDB_CRED_FLAG_DELETED;
_exit:
kcdb_cred_unlock_write();
kcdb_cred_check_and_delete(vcred);
return code;
}
KHMEXP khm_int32 KHMAPI
kcdb_creds_comp_attrib(khm_handle cred1,
khm_handle cred2,
const wchar_t * name)
{
khm_int32 attr_id;
if(KHM_FAILED(kcdb_attrib_get_id(name, &attr_id)))
return 0;
return kcdb_creds_comp_attr(cred1, cred2, attr_id);
}
KHMEXP khm_int32 KHMAPI
kcdb_creds_comp_attr(khm_handle vcred1,
khm_handle vcred2,
khm_int32 attr_id)
{
khm_int32 code = 0;
kcdb_cred * cred1;
kcdb_cred * cred2;
kcdb_attrib * attrib = NULL;
kcdb_type * type = NULL;
if(attr_id < 0 || attr_id > KCDB_ATTR_MAX_ID)
return 0;
cred1 = (kcdb_cred *) vcred1;
cred2 = (kcdb_cred *) vcred2;
kcdb_cred_lock_read();
if(
!kcdb_cred_is_active_cred(vcred1) ||
!kcdb_cred_is_active_cred(vcred2))
goto _exit;
cred1 = (kcdb_cred *) vcred1;
cred2 = (kcdb_cred *) vcred2;
if(KHM_FAILED(kcdb_attrib_get_info(attr_id, &attrib)))
goto _exit;
if(!(attrib->flags & KCDB_ATTR_FLAG_COMPUTED)) {
int nc = 0;
if(!kcdb_cred_val_exist(cred1, attr_id)) {
code = -1;
nc = 1;
}
if(!kcdb_cred_val_exist(cred2, attr_id)) {
code += 1;
nc = 1;
}
if(nc)
goto _exit;
}
if(KHM_FAILED(kcdb_type_get_info(attrib->type, &type)))
goto _exit;
if(attrib->flags & KCDB_ATTR_FLAG_COMPUTED) {
khm_octet vbuf[KCDB_MAXCB_NAME * 2];
void * buf1 = NULL;
void * buf2 = NULL;
khm_size cb1;
khm_size cb2;
code = 0;
if(attrib->compute_cb(vcred1, attr_id,
NULL, &cb1) != KHM_ERROR_TOO_LONG)
goto _exit_1;
if(attrib->compute_cb(vcred2, attr_id,
NULL, &cb2) != KHM_ERROR_TOO_LONG)
goto _exit_1;
if(cb1) {
if (cb1 < sizeof(vbuf))
buf1 = vbuf;
else
buf1 = PMALLOC(cb1);
if(KHM_FAILED(attrib->compute_cb(vcred1, attr_id, buf1, &cb1)))
goto _exit_1;
}
if(cb2) {
if (cb1 + cb2 < sizeof(vbuf))
buf2 = vbuf + cb1;
else
buf2 = PMALLOC(cb2);
if(KHM_FAILED(attrib->compute_cb(vcred2, attr_id, buf2, &cb2)))
goto _exit_1;
}
code = type->comp(buf1, cb1,
buf2, cb2);
_exit_1:
if(buf1 && (buf1 < (void *)vbuf ||
buf1 >= (void*)(vbuf + sizeof(vbuf))))
PFREE(buf1);
if(buf2 && (buf2 < (void *)vbuf ||
buf2 >= (void *)(vbuf + sizeof(vbuf))))
PFREE(buf2);
} else {
code = type->comp(
kcdb_cred_buf_get(cred1, attr_id),
kcdb_cred_buf_size(cred1, attr_id),
kcdb_cred_buf_get(cred2, attr_id),
kcdb_cred_buf_size(cred2, attr_id));
}
_exit:
kcdb_cred_unlock_read();
if(attrib)
kcdb_attrib_release_info(attrib);
if(type)
kcdb_type_release_info(type);
return code;
}
KHMEXP khm_int32 KHMAPI
kcdb_creds_is_equal(khm_handle vcred1,
khm_handle vcred2)
{
khm_int32 code = 0;
kcdb_cred * cred1;
kcdb_cred * cred2;
kcdb_cred_lock_read();
if(!kcdb_cred_is_active_cred(vcred1) ||
!kcdb_cred_is_active_cred(vcred2)) {
code = FALSE;
goto _exit;
}
if(vcred1 == vcred2) {
code = TRUE;
goto _exit;
}
cred1 = vcred1;
cred2 = vcred2;
if(cred1->identity == cred2->identity &&
cred1->type == cred2->type &&
!wcscmp(cred1->name, cred2->name)) {
kcdb_credtype * type;
code = TRUE;
if (KHM_SUCCEEDED(kcdb_credtype_get_info(cred1->type, &type))) {
if (type->is_equal &&
(*type->is_equal)(vcred1, vcred2, NULL))
code = 0;
kcdb_credtype_release_info(type);
}
}
_exit:
kcdb_cred_unlock_read();
return code;
}
KHMEXP khm_int32 KHMAPI
kcdb_cred_get_flags(khm_handle vcred,
khm_int32 * pflags)
{
khm_int32 f;
khm_int32 rv = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
int release_lock = TRUE;
if (pflags == NULL)
return KHM_ERROR_INVALID_PARAM;
kcdb_cred_lock_read();
if (!kcdb_cred_is_active_cred(vcred)) {
*pflags = 0;
rv = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = vcred;
f = cred->flags;
if (!(f & KCDB_CRED_FLAG_EXPIRED) &&
kcdb_cred_buf_exist(cred, KCDB_ATTR_EXPIRE)) {
FILETIME ftc;
GetSystemTimeAsFileTime(&ftc);
if (CompareFileTime(&ftc, ((FILETIME *)
kcdb_cred_buf_get(cred, KCDB_ATTR_EXPIRE)))
>= 0)
f |= KCDB_CRED_FLAG_EXPIRED;
}
#if 0
if (!(f & KCDB_CRED_FLAG_INVALID)) {
if (f & KCDB_CRED_FLAG_RENEWABLE) {
if (kcdb_cred_buf_exist(cred, KCDB_ATTR_RENEW_EXPIRE)) {
FILETIME ftc;
GetSystemTimeAsFileTime(&ftc);
if (CompareFileTime(&ftc, ((FILETIME *)
kcdb_cred_buf_get(cred, KCDB_ATTR_RENEW_EXPIRE))) >= 0)
f |= KCDB_CRED_FLAG_INVALID;
}
} else {
if (f & KCDB_CRED_FLAG_EXPIRED)
f |= KCDB_CRED_FLAG_INVALID;
}
}
if (f != cred->flags) {
kcdb_cred_unlock_read();
kcdb_cred_lock_write();
if (kcdb_cred_is_active_cred(vcred))
cred->flags = f;
else {
rv = KHM_ERROR_INVALID_PARAM;
f = 0;
}
kcdb_cred_unlock_write();
release_lock = FALSE;
}
#endif
*pflags = f;
_exit:
if (release_lock)
kcdb_cred_unlock_read();
return rv;
}
KHMEXP khm_int32 KHMAPI kcdb_cred_set_flags(
khm_handle vcred,
khm_int32 flags,
khm_int32 mask)
{
khm_int32 rv = KHM_ERROR_SUCCESS;
kcdb_cred * cred;
kcdb_cred_lock_write();
if(!kcdb_cred_is_active_cred(vcred)) {
rv = KHM_ERROR_INVALID_PARAM;
goto _exit;
}
cred = vcred;
flags &= ~(KCDB_CRED_FLAG_DELETED);
mask &= ~(KCDB_CRED_FLAG_DELETED);
cred->flags =
(cred->flags & (~mask)) |
(flags & mask);
_exit:
kcdb_cred_unlock_write();
return rv;
}