Skip to content

Commit da16d0a

Browse files
committed
Fix crash in acquiring credentials
When a creedntial store is provide but no name is provided we end up crashing by dereferencing the name. Allow the request to proceed without a name, as it may be selected out of a credential file, but if none was found, return an error. Signed-off-by: Simo Sorce <[email protected]>
1 parent 588d6a1 commit da16d0a

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

src/gss_creds.c

+29-25
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,11 @@ static int get_user_file_creds(const char *filename,
161161
cred->type = GSSNTLM_CRED_USER;
162162
cred->cred.user.user.type = GSSNTLM_NAME_USER;
163163
if (dom) {
164+
free(cred->cred.user.user.data.user.domain);
164165
cred->cred.user.user.data.user.domain = strdup(dom);
165166
if (!cred->cred.user.user.data.user.domain) return ENOMEM;
166167
}
168+
free(cred->cred.user.user.data.user.name);
167169
cred->cred.user.user.data.user.name = strdup(usr);
168170
if (!cred->cred.user.user.data.user.name) return ENOMEM;
169171

@@ -235,52 +237,51 @@ static int get_creds_from_store(struct gssntlm_name *name,
235237
uint32_t i;
236238
int ret;
237239

238-
/* special case to let server creds carry a keyfile */
239-
if (name->type == GSSNTLM_NAME_SERVER) {
240-
const char *keyfile = NULL;
241-
cred->type = GSSNTLM_CRED_SERVER;
242-
ret = gssntlm_copy_name(name, &cred->cred.server.name);
243-
if (ret) return ret;
244-
for (i = 0; i < cred_store->count; i++) {
245-
if (strcmp(cred_store->elements[i].key,
246-
GSS_NTLMSSP_CS_KEYFILE) == 0) {
247-
keyfile = cred_store->elements[i].value;
240+
if (name) {
241+
/* special case to let server creds carry a keyfile */
242+
if (name->type == GSSNTLM_NAME_SERVER) {
243+
const char *keyfile = NULL;
244+
cred->type = GSSNTLM_CRED_SERVER;
245+
ret = gssntlm_copy_name(name, &cred->cred.server.name);
246+
if (ret) return ret;
247+
for (i = 0; i < cred_store->count; i++) {
248+
if (strcmp(cred_store->elements[i].key,
249+
GSS_NTLMSSP_CS_KEYFILE) == 0) {
250+
keyfile = cred_store->elements[i].value;
251+
}
248252
}
249-
}
250-
if (keyfile) {
251-
cred->cred.server.keyfile = strdup(keyfile);
252-
if (cred->cred.server.keyfile == NULL) {
253-
return errno;
253+
if (keyfile) {
254+
cred->cred.server.keyfile = strdup(keyfile);
255+
if (cred->cred.server.keyfile == NULL) {
256+
return errno;
257+
}
254258
}
259+
return 0;
255260
}
256-
return 0;
261+
262+
if (name->type != GSSNTLM_NAME_USER) return ENOENT;
263+
264+
ret = gssntlm_copy_name(name, &cred->cred.user.user);
265+
if (ret) return ret;
257266
}
258267

259268
/* so far only user options can be defined in the cred_store */
260-
if (name->type != GSSNTLM_NAME_USER) return ENOENT;
261-
262269
cred->type = GSSNTLM_CRED_USER;
263-
ret = gssntlm_copy_name(name, &cred->cred.user.user);
264-
if (ret) return ret;
265270

266271
for (i = 0; i < cred_store->count; i++) {
267272
if (strcmp(cred_store->elements[i].key, GSS_NTLMSSP_CS_DOMAIN) == 0) {
268-
/* ignore duplicates */
269-
if (cred->cred.user.user.data.user.domain) continue;
273+
free(cred->cred.user.user.data.user.domain);
270274
cred->cred.user.user.data.user.domain =
271275
strdup(cred_store->elements[i].value);
272276
if (!cred->cred.user.user.data.user.domain) return ENOMEM;
273277
}
274278
if (strcmp(cred_store->elements[i].key, GSS_NTLMSSP_CS_NTHASH) == 0) {
275-
/* ignore duplicates */
276-
if (cred->cred.user.nt_hash.length) continue;
277279
ret = hex_to_key(cred_store->elements[i].value,
278280
&cred->cred.user.nt_hash);
279281
if (ret) return ret;
280282
}
281283
if ((strcmp(cred_store->elements[i].key, GSS_NTLMSSP_CS_PASSWORD) == 0) ||
282284
(strcmp(cred_store->elements[i].key, GENERIC_CS_PASSWORD) == 0)) {
283-
if (cred->cred.user.nt_hash.length) continue;
284285
cred->cred.user.nt_hash.length = 16;
285286
ret = NTOWFv1(cred_store->elements[i].value,
286287
&cred->cred.user.nt_hash);
@@ -301,6 +302,9 @@ static int get_creds_from_store(struct gssntlm_name *name,
301302
}
302303
}
303304

305+
/* now check if a user name was found, if not error out */
306+
if (cred->cred.user.user.data.user.name == NULL) return ENOENT;
307+
304308
return 0;
305309
}
306310

0 commit comments

Comments
 (0)