~ubuntu-branches/ubuntu/precise/krb5/precise-updates

« back to all changes in this revision

Viewing changes to src/windows/identity/kcreddb/buf.c

  • Committer: Package Import Robot
  • Author(s): Sam Hartman
  • Date: 2011-12-01 19:34:41 UTC
  • mfrom: (28.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20111201193441-9tipg3aru1jsidyv
Tags: 1.10+dfsg~alpha1-6
* Fix segfault with unknown hostnames in krb5_sname_to_principal,
  Closes: #650671
* Indicate that this library breaks libsmbclient versions that depend on
  krb5_locate_kdc, Closes: #650603, #650611

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (c) 2005 Massachusetts Institute of Technology
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person
5
 
 * obtaining a copy of this software and associated documentation
6
 
 * files (the "Software"), to deal in the Software without
7
 
 * restriction, including without limitation the rights to use, copy,
8
 
 * modify, merge, publish, distribute, sublicense, and/or sell copies
9
 
 * of the Software, and to permit persons to whom the Software is
10
 
 * furnished to do so, subject to the following conditions:
11
 
 *
12
 
 * The above copyright notice and this permission notice shall be
13
 
 * included in all copies or substantial portions of the Software.
14
 
 *
15
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19
 
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20
 
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21
 
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
 
 * SOFTWARE.
23
 
 */
24
 
 
25
 
/* $Id$ */
26
 
 
27
 
#include<kcreddbinternal.h>
28
 
#include<assert.h>
29
 
 
30
 
void kcdb_buf_new(kcdb_buf * buf, khm_size n_fields)
31
 
{
32
 
    buf->buffer = PMALLOC(KCDB_BUF_CBBUF_INITIAL);
33
 
    buf->cb_buffer = KCDB_BUF_CBBUF_INITIAL;
34
 
    buf->cb_used = 0;
35
 
 
36
 
    if(n_fields == KCDB_BUF_DEFAULT)
37
 
        n_fields = KCDB_BUF_FIELDS_INITIAL;
38
 
 
39
 
    assert(n_fields < KCDB_BUF_MAX_SLOTS);
40
 
 
41
 
    buf->n_fields = n_fields;
42
 
    buf->nc_fields = UBOUNDSS(n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
43
 
    buf->fields = PMALLOC(sizeof(buf->fields[0]) * buf->n_fields);
44
 
    ZeroMemory(buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
45
 
}
46
 
 
47
 
void kcdb_buf_delete(kcdb_buf * buf)
48
 
{
49
 
    buf->cb_buffer = 0;
50
 
    buf->cb_used = 0;
51
 
    if(buf->buffer)
52
 
        PFREE(buf->buffer);
53
 
    buf->buffer = NULL;
54
 
 
55
 
    buf->n_fields = 0;
56
 
    buf->nc_fields = 0;
57
 
    if(buf->fields)
58
 
        PFREE(buf->fields);
59
 
    buf->fields = NULL;
60
 
}
61
 
 
62
 
static void kcdb_buf_assert_size(kcdb_buf * buf, khm_size cbsize)
63
 
{
64
 
    khm_size new_size;
65
 
    void * new_buf;
66
 
 
67
 
    /* should be less than or equal to the max signed 32 bit int */
68
 
    assert(cbsize <= KHM_INT32_MAX);
69
 
    if(cbsize <= buf->cb_buffer)
70
 
        return;
71
 
 
72
 
    new_size = UBOUNDSS(cbsize, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
73
 
 
74
 
    assert(new_size > buf->cb_buffer && new_size > 0);
75
 
 
76
 
    new_buf = PMALLOC(new_size);
77
 
    assert(new_buf != NULL);
78
 
 
79
 
    memcpy(new_buf, buf->buffer, buf->cb_used);
80
 
    PFREE(buf->buffer);
81
 
    buf->buffer = new_buf;
82
 
}
83
 
 
84
 
void kcdb_buf_alloc(kcdb_buf * buf, khm_size slot, khm_ui_2 id, khm_size cbsize)
85
 
{
86
 
    khm_size cbnew;
87
 
    khm_ssize cbdelta;
88
 
    khm_size cbold;
89
 
    kcdb_buf_field * f;
90
 
 
91
 
    cbnew = UBOUND32(cbsize);
92
 
 
93
 
    assert(slot <= KCDB_BUF_APPEND);
94
 
 
95
 
    if(slot == KCDB_BUF_APPEND) {
96
 
        slot = kcdb_buf_slot_by_id(buf, id);
97
 
        if(slot == KCDB_BUF_INVALID_SLOT)
98
 
            slot = buf->n_fields;
99
 
    }
100
 
 
101
 
    assert(slot < KCDB_BUF_MAX_SLOTS);
102
 
 
103
 
    if((slot + 1) > buf->nc_fields) {
104
 
        kcdb_buf_field * nf;
105
 
        khm_size ns;
106
 
 
107
 
        ns = UBOUNDSS((slot + 1), KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
108
 
 
109
 
        nf = PMALLOC(sizeof(buf->fields[0]) * ns);
110
 
        memcpy(nf, buf->fields, sizeof(buf->fields[0]) * buf->n_fields);
111
 
 
112
 
        if(ns > buf->n_fields)
113
 
            memset(&(nf[buf->n_fields]), 0, sizeof(buf->fields[0]) * (ns - buf->n_fields));
114
 
 
115
 
        PFREE(buf->fields);
116
 
        buf->fields = nf;
117
 
        buf->nc_fields = ns;
118
 
    }
119
 
 
120
 
    if((slot + 1) > buf->n_fields)
121
 
        buf->n_fields = slot + 1;
122
 
 
123
 
    f = &(buf->fields[slot]);
124
 
 
125
 
    if(f->flags & KCDB_CREDF_FLAG_ALLOCD) {
126
 
        /* there's already an allocation.  we have to resize it to
127
 
           accomodate the new size */
128
 
        cbold = UBOUND32(f->cbsize);
129
 
        /* demote before substraction */
130
 
        cbdelta = ((khm_ssize) cbnew) - (khm_ssize) cbold;
131
 
 
132
 
        if(cbnew > cbold) {
133
 
            kcdb_buf_assert_size(buf, buf->cb_used + cbdelta);
134
 
        }
135
 
 
136
 
        if(buf->cb_used > f->offset + cbold) {
137
 
            khm_size i;
138
 
 
139
 
            memmove(
140
 
                ((BYTE *) buf->buffer) + (f->offset + cbnew),
141
 
                ((BYTE *) buf->buffer) + (f->offset + cbold),
142
 
                buf->cb_used - (f->offset + cbold));
143
 
 
144
 
            for(i=0; i < (int) buf->n_fields; i++) {
145
 
                if(i != slot &&
146
 
                    (buf->fields[i].flags & KCDB_CREDF_FLAG_ALLOCD) &&
147
 
                    buf->fields[i].offset > f->offset)
148
 
                {
149
 
                    buf->fields[i].offset =
150
 
                        (khm_ui_4)(((khm_ssize) buf->fields[i].offset) + cbdelta);
151
 
                }
152
 
            }
153
 
        }
154
 
 
155
 
        /* demote integer before adding signed quantity */
156
 
        buf->cb_used = (khm_size)(((khm_ssize) buf->cb_used) + cbdelta);
157
 
 
158
 
        f->cbsize = (khm_ui_4) cbsize;
159
 
 
160
 
    } else {
161
 
        kcdb_buf_assert_size(buf, buf->cb_used + cbnew);
162
 
        f->offset = (khm_ui_4) buf->cb_used;
163
 
        f->cbsize = (khm_ui_4) cbsize;
164
 
        buf->cb_used += cbnew;
165
 
    }
166
 
 
167
 
    if(cbsize == 0) {
168
 
        f->flags &= ~KCDB_CREDF_FLAG_ALLOCD;
169
 
        f->flags &= ~KCDB_CREDF_FLAG_DATA;
170
 
        f->id = KCDB_BUFF_ID_INVALID;
171
 
    } else {
172
 
        f->flags |= KCDB_CREDF_FLAG_ALLOCD;
173
 
        f->id = id;
174
 
    }
175
 
}
176
 
 
177
 
void kcdb_buf_dup(kcdb_buf * dest, const kcdb_buf * src)
178
 
{
179
 
    khm_size cb_buf;
180
 
    khm_size nc_fields;
181
 
 
182
 
    cb_buf = UBOUNDSS(src->cb_used, KCDB_BUF_CBBUF_INITIAL, KCDB_BUF_CBBUF_GROWTH);
183
 
#if 0
184
 
        /* replaced by UBOUNDSS() above */
185
 
        (src->cb_used <= kcdb_cred_initial_size)? kcdb_cred_initial_size:
186
 
        kcdb_cred_initial_size +
187
 
            (((src->cb_used - (kcdb_cred_initial_size + 1)) / kcdb_cred_growth_factor + 1) * kcdb_cred_growth_factor);
188
 
#endif
189
 
 
190
 
    kcdb_buf_delete(dest);
191
 
 
192
 
    dest->cb_buffer = cb_buf;
193
 
    dest->cb_used = src->cb_used;
194
 
    dest->buffer = PMALLOC(cb_buf);
195
 
    memcpy(dest->buffer, src->buffer, src->cb_used);
196
 
 
197
 
    nc_fields = UBOUNDSS(src->n_fields, KCDB_BUF_FIELDS_INITIAL, KCDB_BUF_FIELDS_GROWTH);
198
 
    dest->nc_fields = nc_fields;
199
 
    dest->n_fields = src->n_fields;
200
 
    dest->fields = PMALLOC(nc_fields * sizeof(dest->fields[0]));
201
 
    memcpy(dest->fields, src->fields, src->n_fields * sizeof(dest->fields[0]));
202
 
    if(dest->n_fields < dest->nc_fields)
203
 
        memset(&(dest->fields[dest->n_fields]), 0, (src->nc_fields - src->n_fields) * sizeof(dest->fields[0]));
204
 
}
205
 
 
206
 
void kcdb_buf_set_value(kcdb_buf * buf, khm_size slot, khm_ui_2 id, void * src, khm_size cb_src)
207
 
{
208
 
    void * dest;
209
 
    kcdb_buf_alloc(buf, slot, id, cb_src);
210
 
    if(slot == KCDB_BUF_APPEND) {
211
 
        slot = kcdb_buf_slot_by_id(buf, id);
212
 
        if(slot == KCDB_BUF_INVALID_SLOT) {
213
 
#ifdef DEBUG
214
 
            assert(FALSE);
215
 
#else
216
 
            return;
217
 
#endif
218
 
        }
219
 
    }
220
 
    if(kcdb_buf_exist(buf, slot)) {
221
 
        dest = kcdb_buf_get(buf, slot);
222
 
        memcpy(dest, src, cb_src);
223
 
 
224
 
        buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA;
225
 
    }
226
 
}
227
 
 
228
 
int kcdb_buf_exist(kcdb_buf * buf, khm_size slot)
229
 
{
230
 
    if(slot >= buf->n_fields)
231
 
        return 0;
232
 
    return (buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD);
233
 
}
234
 
 
235
 
int kcdb_buf_val_exist(kcdb_buf * buf, khm_size slot)
236
 
{
237
 
    if(slot >= buf->n_fields)
238
 
        return 0;
239
 
    return (buf->fields[slot].flags & KCDB_CREDF_FLAG_DATA);
240
 
}
241
 
 
242
 
void * kcdb_buf_get(kcdb_buf * buf, khm_size slot)
243
 
{
244
 
    if(slot >= buf->n_fields ||
245
 
        !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
246
 
        return NULL;
247
 
    return (((BYTE *) buf->buffer) + buf->fields[slot].offset);
248
 
}
249
 
 
250
 
khm_size kcdb_buf_size(kcdb_buf * buf, khm_size slot)
251
 
{
252
 
    if(slot >= buf->n_fields ||
253
 
        !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
254
 
        return 0;
255
 
    return (buf->fields[slot].cbsize);
256
 
}
257
 
 
258
 
void kcdb_buf_set_value_flag(kcdb_buf * buf, khm_size slot)
259
 
{
260
 
    if(slot >= buf->n_fields ||
261
 
        !(buf->fields[slot].flags & KCDB_CREDF_FLAG_ALLOCD))
262
 
        return;
263
 
 
264
 
    (buf->fields[slot].flags |= KCDB_CREDF_FLAG_DATA);
265
 
}
266
 
 
267
 
khm_size kcdb_buf_slot_by_id(kcdb_buf * buf, khm_ui_2 id)
268
 
{
269
 
    int i;
270
 
 
271
 
    for(i=0; i < (int) buf->n_fields; i++) {
272
 
        if(buf->fields[i].id == id)
273
 
            break;
274
 
    }
275
 
 
276
 
    if(i < (int) buf->n_fields)
277
 
        return i;
278
 
    else
279
 
        return KCDB_BUF_INVALID_SLOT;
280
 
}
281
 
 
282
 
/* API for accessing generic buffers */
283
 
 
284
 
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr(
285
 
    khm_handle  record,
286
 
    khm_int32   attr_id,
287
 
    khm_int32 * attr_type,
288
 
    void *      buffer,
289
 
    khm_size *  pcb_buf)
290
 
{
291
 
    if(kcdb_cred_is_active_cred(record))
292
 
        return kcdb_cred_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
293
 
    else if(kcdb_is_active_identity(record))
294
 
        return kcdb_identity_get_attr(record, attr_id, attr_type, buffer, pcb_buf);
295
 
    else
296
 
        return KHM_ERROR_INVALID_PARAM;
297
 
}
298
 
 
299
 
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib(
300
 
    khm_handle  record,
301
 
    const wchar_t *   attr_name,
302
 
    khm_int32 * attr_type,
303
 
    void *      buffer,
304
 
    khm_size *  pcb_buf)
305
 
{
306
 
    if(kcdb_cred_is_active_cred(record))
307
 
        return kcdb_cred_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
308
 
    else if(kcdb_is_active_identity(record))
309
 
        return kcdb_identity_get_attrib(record, attr_name, attr_type, buffer, pcb_buf);
310
 
    else
311
 
        return KHM_ERROR_INVALID_PARAM;
312
 
}
313
 
 
314
 
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attr_string(
315
 
    khm_handle  record,
316
 
    khm_int32   attr_id,
317
 
    wchar_t *   buffer,
318
 
    khm_size *  pcbbuf,
319
 
    khm_int32  flags)
320
 
{
321
 
    if(kcdb_cred_is_active_cred(record))
322
 
        return kcdb_cred_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
323
 
    else if(kcdb_is_active_identity(record))
324
 
        return kcdb_identity_get_attr_string(record, attr_id, buffer, pcbbuf, flags);
325
 
    else
326
 
        return KHM_ERROR_INVALID_PARAM;
327
 
}
328
 
 
329
 
KHMEXP khm_int32 KHMAPI kcdb_buf_get_attrib_string(
330
 
    khm_handle  record,
331
 
    const wchar_t *   attr_name,
332
 
    wchar_t *   buffer,
333
 
    khm_size *  pcbbuf,
334
 
    khm_int32   flags)
335
 
{
336
 
    if(kcdb_cred_is_active_cred(record))
337
 
        return kcdb_cred_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
338
 
    else if(kcdb_is_active_identity(record))
339
 
        return kcdb_identity_get_attrib_string(record, attr_name, buffer, pcbbuf, flags);
340
 
    else
341
 
        return KHM_ERROR_INVALID_PARAM;
342
 
}
343
 
 
344
 
KHMEXP khm_int32 KHMAPI kcdb_buf_set_attr(
345
 
    khm_handle  record,
346
 
    khm_int32   attr_id,
347
 
    void *      buffer,
348
 
    khm_size    cbbuf)
349
 
{
350
 
    if(kcdb_cred_is_active_cred(record))
351
 
        return kcdb_cred_set_attr(record, attr_id, buffer, cbbuf);
352
 
    else if(kcdb_is_active_identity(record))
353
 
        return kcdb_identity_set_attr(record, attr_id, buffer, cbbuf);
354
 
    else
355
 
        return KHM_ERROR_INVALID_PARAM;
356
 
}
357
 
 
358
 
KHMEXP khm_int32 KHMAPI kcdb_buf_set_attrib(
359
 
    khm_handle  record,
360
 
    const wchar_t *   attr_name,
361
 
    void *      buffer,
362
 
    khm_size    cbbuf)
363
 
{
364
 
    if(kcdb_cred_is_active_cred(record))
365
 
        return kcdb_cred_set_attrib(record, attr_name, buffer, cbbuf);
366
 
    else if(kcdb_is_active_identity(record))
367
 
        return kcdb_identity_set_attrib(record, attr_name, buffer, cbbuf);
368
 
    else
369
 
        return KHM_ERROR_INVALID_PARAM;
370
 
}
371
 
 
372
 
KHMEXP khm_int32 KHMAPI kcdb_buf_hold(khm_handle  record)
373
 
{
374
 
    if(kcdb_cred_is_active_cred(record))
375
 
        return kcdb_cred_hold(record);
376
 
    else if(kcdb_is_active_identity(record))
377
 
        return kcdb_identity_hold(record);
378
 
    else
379
 
        return KHM_ERROR_INVALID_PARAM;
380
 
}
381
 
 
382
 
KHMEXP khm_int32 KHMAPI kcdb_buf_release(khm_handle record)
383
 
{
384
 
    if(kcdb_cred_is_active_cred(record))
385
 
        return kcdb_cred_release(record);
386
 
    else if(kcdb_is_active_identity(record))
387
 
        return kcdb_identity_release(record);
388
 
    else
389
 
        return KHM_ERROR_INVALID_PARAM;
390
 
}