1/*
2 * Copyright (c) 2004, PADL Software Pty Ltd.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * 3. Neither the name of PADL Software nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32/* $FreeBSD$ */
33/* RCSID("$Id: gss_set_sec_context_option.c 19928 2007-01-16 10:37:54Z lha $"); */
34
35#include <gssapi/gssapi.h>
36
37#include "mech_switch.h"
38#include "context.h"
39
40OM_uint32
41gss_set_sec_context_option (OM_uint32 *minor_status,
42			    gss_ctx_id_t *context_handle,
43			    const gss_OID object,
44			    const gss_buffer_t value)
45{
46	struct _gss_context	*ctx;
47	OM_uint32		major_status;
48	struct _gss_mech_switch	*m;
49	int			one_ok = 0;
50
51	*minor_status = 0;
52
53	if (context_handle == NULL) {
54		_gss_load_mech();
55		major_status = GSS_S_BAD_MECH;
56		SLIST_FOREACH(m, &_gss_mechs, gm_link) {
57			if (!m->gm_set_sec_context_option)
58				continue;
59			major_status = m->gm_set_sec_context_option(
60				minor_status,
61				NULL, object, value);
62			if (major_status == GSS_S_COMPLETE)
63				one_ok = 1;
64		}
65		if (one_ok) {
66			*minor_status = 0;
67			return (GSS_S_COMPLETE);
68		}
69		return (major_status);
70	}
71
72	ctx = (struct _gss_context *) *context_handle;
73
74	if (ctx == NULL)
75		return (GSS_S_NO_CONTEXT);
76
77	m = ctx->gc_mech;
78
79	if (m == NULL)
80		return (GSS_S_BAD_MECH);
81
82	if (m->gm_set_sec_context_option != NULL) {
83		major_status = m->gm_set_sec_context_option(minor_status,
84		    &ctx->gc_ctx, object, value);
85		if (major_status != GSS_S_COMPLETE)
86			_gss_mg_error(m, major_status, *minor_status);
87	} else
88		major_status = (GSS_S_BAD_MECH);
89
90	return (major_status);
91}
92
93