Skip to content

Commit b9e59df

Browse files
committed
Move attribute names to allocated strings
Unfortunately as our interfaces allow for importing and exporting the gssntlmssp context via serialization we need to use allocated strings or fixed size buffers. In this case, given the attribute names are arbitrary strings I prefer to allocate the names for ease of handling. The bulk of the data for sids is in the values anyway so it is a small price to pay to have a strdup() for the attribute name. Signed-off-by: Simo Sorce <[email protected]>
1 parent 575e3b9 commit b9e59df

File tree

4 files changed

+61
-116
lines changed

4 files changed

+61
-116
lines changed

src/gss_names.c

Lines changed: 7 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,11 @@ int gssntlm_copy_attrs(const struct gssntlm_name_attribute *src,
306306
}
307307

308308
for (size_t i = 0; i < attrs_count; i++) {
309-
/* read-only persistent data ptr can be just copied */
310-
copied_attrs[i].attr_name = src[i].attr_name;
309+
copied_attrs[i].attr_name = strdup(src[i].attr_name);
310+
if (copied_attrs[i].attr_name == NULL) {
311+
gssntlm_release_attrs(&copied_attrs);
312+
return ENOMEM;
313+
}
311314
copied_attrs[i].attr_value.length = src[i].attr_value.length;
312315
copied_attrs[i].attr_value.value = malloc(src[i].attr_value.length);
313316
if (copied_attrs[i].attr_value.value == NULL) {
@@ -323,69 +326,13 @@ int gssntlm_copy_attrs(const struct gssntlm_name_attribute *src,
323326
return 0;
324327
}
325328

326-
/* Low-level func with buffer ownership transfer
327-
* attr_name - read-only static string, should not be released
328-
* attr_value - ownership of that buffer is MOVED to dst
329-
* (MUST NOT BE RELEASED from caller side) */
330-
int gssntlm_append_attr(const char *attr_name, gss_buffer_t attr_value,
331-
struct gssntlm_name *dst)
332-
{
333-
size_t prev_attrs_count = gssntlm_get_attrs_count(dst->attrs);
334-
/* 1 for new attribute +1 for terminator entry */
335-
size_t new_attrs_count = prev_attrs_count + 2;
336-
struct gssntlm_name_attribute *attrs;
337-
338-
if (!attr_name || !attr_value || !dst) {
339-
return ERR_NOARG;
340-
}
341-
342-
/* Increase buffer - if there was no any attributes before,
343-
* realloc is identical to malloc */
344-
attrs = realloc(dst->attrs,
345-
new_attrs_count * sizeof(struct gssntlm_name_attribute));
346-
if (attrs == NULL) {
347-
return ENOMEM;
348-
}
349-
dst->attrs = attrs;
350-
351-
attrs[prev_attrs_count].attr_name = attr_name;
352-
attrs[prev_attrs_count].attr_value.value = attr_value->value;
353-
attrs[prev_attrs_count].attr_value.length = attr_value->length;
354-
355-
/* Fill the last terminator entry with zeroes
356-
beacuse realloc does not init added memory */
357-
memset(&attrs[prev_attrs_count + 1], 0, sizeof(struct gssntlm_name_attribute));
358-
359-
return 0;
360-
}
361-
362-
int gssntlm_append_attr_str(const char *attr_name, const char *attr_value,
363-
struct gssntlm_name *dst)
364-
{
365-
int ret;
366-
gss_buffer_desc buf;
367-
if (!attr_value) {
368-
return ERR_NOARG;
369-
}
370-
buf.value = strdup(attr_value);
371-
if (!buf.value) {
372-
return ENOMEM;
373-
}
374-
buf.length = strlen(attr_value) + 1; /* +1 for EOL */
375-
ret = gssntlm_append_attr(attr_name, &buf, dst);
376-
if (ret) {
377-
free(buf.value);
378-
}
379-
return ret;
380-
}
381-
382329
struct gssntlm_name_attribute *gssntlm_find_attr(
383330
struct gssntlm_name_attribute *attrs,
384331
const char *attr_name,
385332
size_t attr_name_len)
386333
{
387334
for (size_t i = 0; attrs && (attrs[i].attr_name != NULL); i++) {
388-
/* We store attr_name as const static zero-terminated string, so
335+
/* We store attr_name as a zero-terminated string, so
389336
* it is always zero-terminated */
390337
if (attr_name_len == strlen(attrs[i].attr_name) &&
391338
strncasecmp(attrs[i].attr_name, attr_name, attr_name_len) == 0) {
@@ -398,6 +345,7 @@ struct gssntlm_name_attribute *gssntlm_find_attr(
398345
void gssntlm_release_attrs(struct gssntlm_name_attribute **attrs)
399346
{
400347
for (size_t i = 0; *attrs && (*attrs)[i].attr_name != NULL; i++) {
348+
free((*attrs)[i].attr_name);
401349
free((*attrs)[i].attr_value.value);
402350
}
403351
safefree(*attrs);

src/gss_ntlmssp.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@
4141
#define NTLMSSP_CTX_FLAG_AUTH_WITH_MIC 0x04 /* Auth MIC was created */
4242

4343
struct gssntlm_name_attribute {
44-
const char *attr_name; /* Read-only static string, should not be released */
45-
/* NULL is used to indicate */
46-
/* the terminating element of array */
44+
char *attr_name; /* NULL indicates array termination */
4745
gss_buffer_desc attr_value;
4846
};
4947

src/winbind.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,33 @@ static uint32_t format_sids_as_name_attribute(
216216
const struct wbcAuthUserInfo *wbc_info,
217217
struct gssntlm_name_attribute **auth_attrs)
218218
{
219-
char *sids_buf, *sids_buf_realloced;
220-
size_t offset = 0;
221-
struct gssntlm_name_attribute *attrs;
222219
size_t worst_sids_list_len = WBC_SID_STRING_BUFLEN * wbc_info->num_sids;
220+
struct gssntlm_name_attribute *attrs = NULL;
221+
char *sids_buf_realloced;
222+
char *sids_buf = NULL;
223+
char *name = NULL;
224+
size_t offset = 0;
225+
int ret = EFAULT;
223226

224227
/* Allocate buffers */
228+
name = strdup(gssntlmssp_sids_urn);
229+
if (name == NULL) {
230+
ret = ENOMEM;
231+
goto done;
232+
}
225233

226234
/* 1 for returned attribute +1 for termiator entry */
227235
attrs = calloc(2, sizeof(struct gssntlm_name_attribute));
228236
if (attrs == NULL) {
229-
return ENOMEM;
237+
ret = ENOMEM;
238+
goto done;
230239
}
231240

232241
/* sids buffer is allocated with the worst-case size */
233242
sids_buf = malloc(worst_sids_list_len);
234243
if (sids_buf == NULL) {
235-
free(attrs);
236-
return ENOMEM;
244+
ret = ENOMEM;
245+
goto done;
237246
}
238247

239248
/* Construct name attributes string */
@@ -259,10 +268,20 @@ static uint32_t format_sids_as_name_attribute(
259268
sids_buf = sids_buf_realloced;
260269
}
261270

262-
attrs[0].attr_name = gssntlmssp_sids_urn;
271+
ret = 0;
272+
273+
done:
274+
if (ret) {
275+
free(name);
276+
free(attrs);
277+
free(sids_buf);
278+
return ret;
279+
}
280+
281+
attrs[0].attr_name = name;
263282
attrs[0].attr_value.length = offset;
264283
attrs[0].attr_value.value = sids_buf;
265-
/* attrs[1] will be filled by zeros automatically by calloc */
284+
/* attrs[1] was zeroed by calloc */
266285

267286
*auth_attrs = attrs;
268287

tests/ntlmssptest.c

Lines changed: 26 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2283,18 +2283,18 @@ static void generate_random_binary_blob(char *dst, size_t bytes_count)
22832283
}
22842284

22852285
/* Low-level func with buffer ownership transfer
2286-
* attr_name - read-only static string, should not be released
2287-
* attr_value - ownership of that buffer is MOVED to dst
2288-
* (MUST NOT BE RELEASED from caller side) */
2289-
static int gssntlm_append_attr(const char *attr_name, gss_buffer_t attr_value,
2290-
struct gssntlm_name *dst)
2286+
* name - allocated string with the name of the attribute
2287+
* value - allocated buffer with a value of size 'length'
2288+
*/
2289+
static int gssntlm_append_attr(const char *name, void *value,
2290+
size_t length, struct gssntlm_name *dst)
22912291
{
22922292
size_t prev_attrs_count = gssntlm_get_attrs_count(dst->attrs);
22932293
/* 1 for new attribute +1 for terminator entry */
22942294
size_t new_attrs_count = prev_attrs_count + 2;
22952295
struct gssntlm_name_attribute *attrs;
22962296

2297-
if (!attr_name || !attr_value || !dst) {
2297+
if (!name || !value || !length || !dst) {
22982298
return ERR_NOARG;
22992299
}
23002300

@@ -2307,36 +2307,22 @@ static int gssntlm_append_attr(const char *attr_name, gss_buffer_t attr_value,
23072307
}
23082308
dst->attrs = attrs;
23092309

2310-
attrs[prev_attrs_count].attr_name = attr_name;
2311-
attrs[prev_attrs_count].attr_value.value = attr_value->value;
2312-
attrs[prev_attrs_count].attr_value.length = attr_value->length;
2313-
2314-
/* Fill the last terminator entry with zeroes
2315-
beacuse realloc does not init added memory */
2316-
memset(&attrs[prev_attrs_count + 1], 0, sizeof(struct gssntlm_name_attribute));
2317-
2318-
return 0;
2319-
}
2320-
2321-
static int gssntlm_append_attr_str(const char *attr_name,
2322-
const char *attr_value,
2323-
struct gssntlm_name *dst)
2324-
{
2325-
int ret;
2326-
gss_buffer_desc buf;
2327-
if (!attr_value) {
2328-
return ERR_NOARG;
2329-
}
2330-
buf.value = strdup(attr_value);
2331-
if (!buf.value) {
2310+
attrs[prev_attrs_count].attr_name = strdup(name);
2311+
if (attrs[prev_attrs_count].attr_name == NULL) {
23322312
return ENOMEM;
23332313
}
2334-
buf.length = strlen(attr_value) + 1; /* +1 for EOL */
2335-
ret = gssntlm_append_attr(attr_name, &buf, dst);
2336-
if (ret) {
2337-
free(buf.value);
2314+
attrs[prev_attrs_count].attr_value.value = malloc(length);
2315+
if (attrs[prev_attrs_count].attr_value.value == NULL) {
2316+
safefree(attrs[prev_attrs_count].attr_name);
2317+
return ENOMEM;
23382318
}
2339-
return ret;
2319+
memcpy(attrs[prev_attrs_count].attr_value.value, value, length);
2320+
attrs[prev_attrs_count].attr_value.length = length;
2321+
2322+
/* terminate array */
2323+
attrs[prev_attrs_count + 1].attr_name = NULL;
2324+
2325+
return 0;
23402326
}
23412327

23422328
static int append_sids_list_attr(const char *urn, size_t min_count,
@@ -2352,26 +2338,20 @@ static int append_sids_list_attr(const char *urn, size_t min_count,
23522338
return ENOMEM;
23532339
}
23542340
*length = generate_random_sids_list(str, min_count, max_count);
2355-
ret = gssntlm_append_attr_str(urn, str, name);
2341+
/* append zero terminated string for ease of string handling */
2342+
ret = gssntlm_append_attr(urn, str, strlen(str) + 1, name);
23562343
free(str);
23572344
return ret;
23582345
}
23592346

2360-
static int append_binary_attr(const char *urn, size_t bytes_count,
2347+
static int append_binary_attr(const char *urn, size_t length,
23612348
struct gssntlm_name *name)
23622349
{
2350+
char rndbuf[length];
23632351
int ret;
2364-
gss_buffer_desc buf = { bytes_count, malloc(bytes_count) };
2365-
if (!buf.value) {
2366-
return ENOMEM;
2367-
}
2368-
generate_random_binary_blob(buf.value, bytes_count);
2369-
ret = gssntlm_append_attr(urn, &buf, name);
2370-
/* If append was ok, memory ownership is moved to name;
2371-
if failed, we need to release it here */
2372-
if (ret) {
2373-
free(buf.value);
2374-
}
2352+
generate_random_binary_blob(rndbuf, length);
2353+
ret = gssntlm_append_attr(urn, rndbuf, length, name);
2354+
free(rndbuf);
23752355
return ret;
23762356
}
23772357

0 commit comments

Comments
 (0)