*/
#include "includes.h"
+#include "auth/auth.h"
/* the list of currently registered GENSEC backends */
const static struct gensec_security_ops **generic_security_ops;
return oid_list;
}
-static NTSTATUS gensec_start(struct gensec_security **gensec_security)
+/*
+ note that memory context is the parent context to hang this gensec context off. It may be NULL.
+*/
+static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security)
{
- TALLOC_CTX *mem_ctx;
- /* awaiting a correct fix from metze */
- if (!gensec_init()) {
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- mem_ctx = talloc_init("gensec_security struct");
- if (!mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
(*gensec_security) = talloc_p(mem_ctx, struct gensec_security);
if (!(*gensec_security)) {
- talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
- (*gensec_security)->mem_ctx = mem_ctx;
(*gensec_security)->ops = NULL;
ZERO_STRUCT((*gensec_security)->user);
ZERO_STRUCT((*gensec_security)->default_user);
(*gensec_security)->default_user.name = "";
- (*gensec_security)->default_user.domain = talloc_strdup(mem_ctx, lp_workgroup());
- (*gensec_security)->default_user.realm = talloc_strdup(mem_ctx, lp_realm());
+ (*gensec_security)->default_user.domain = talloc_strdup(*gensec_security, lp_workgroup());
+ (*gensec_security)->default_user.realm = talloc_strdup(*gensec_security, lp_realm());
(*gensec_security)->subcontext = False;
(*gensec_security)->want_features = 0;
+ (*gensec_security)->have_features = 0;
return NT_STATUS_OK;
}
NTSTATUS gensec_subcontext_start(struct gensec_security *parent,
struct gensec_security **gensec_security)
{
- (*gensec_security) = talloc_p(parent->mem_ctx, struct gensec_security);
+ (*gensec_security) = talloc_p(parent, struct gensec_security);
if (!(*gensec_security)) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_OK;
}
-NTSTATUS gensec_client_start(struct gensec_security **gensec_security)
+NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security)
{
NTSTATUS status;
- status = gensec_start(gensec_security);
+ status = gensec_start(mem_ctx, gensec_security);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return status;
}
-NTSTATUS gensec_server_start(struct gensec_security **gensec_security)
+NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security)
{
NTSTATUS status;
- status = gensec_start(gensec_security);
+ status = gensec_start(mem_ctx, gensec_security);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
if (gensec_security->ops->client_start) {
status = gensec_security->ops->client_start(gensec_security);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Faild to start GENSEC client mech %s: %s\n",
+ DEBUG(1, ("Failed to start GENSEC client mech %s: %s\n",
gensec_security->ops->name, nt_errstr(status)));
}
return status;
if (gensec_security->ops->server_start) {
status = gensec_security->ops->server_start(gensec_security);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Faild to start GENSEC server mech %s: %s\n",
+ DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n",
gensec_security->ops->name, nt_errstr(status)));
}
return status;
DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
return NT_STATUS_INVALID_PARAMETER;
}
+ gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE);
if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
- gensec_want_feature(gensec_security, GENSEC_WANT_SIGN);
+ gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
}
if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
- gensec_want_feature(gensec_security, GENSEC_WANT_SIGN);
- gensec_want_feature(gensec_security, GENSEC_WANT_SEAL);
+ gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN);
+ gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL);
}
return gensec_start_mech(gensec_security);
if (!gensec_security->ops->unseal_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
+ if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ return gensec_check_packet(gensec_security, mem_ctx,
+ data, length,
+ whole_pdu, pdu_length,
+ sig);
+ }
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return gensec_security->ops->unseal_packet(gensec_security, mem_ctx,
data, length,
whole_pdu, pdu_length,
if (!gensec_security->ops->check_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
return NT_STATUS_INVALID_PARAMETER;
}
if (!gensec_security->ops->seal_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
+ if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
+ return gensec_sign_packet(gensec_security, mem_ctx,
+ data, length,
+ whole_pdu, pdu_length,
+ sig);
+ }
return NT_STATUS_INVALID_PARAMETER;
}
if (!gensec_security->ops->sign_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
return NT_STATUS_INVALID_PARAMETER;
}
if (!gensec_security->ops->sig_size) {
return 0;
}
- if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) {
+ if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
return 0;
}
if (!gensec_security->ops->session_key) {
return NT_STATUS_NOT_IMPLEMENTED;
}
- if (!(gensec_security->want_features & GENSEC_WANT_SESSION_KEY)) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
return gensec_security->ops->session_key(gensec_security, session_key);
}
void gensec_end(struct gensec_security **gensec_security)
{
+ if (!*gensec_security) {
+ return;
+ }
if ((*gensec_security)->ops) {
(*gensec_security)->ops->end(*gensec_security);
}
(*gensec_security)->private_data = NULL;
- if (!(*gensec_security)->subcontext) {
- /* don't destory this if this is a subcontext - it belongs to the parent */
- talloc_destroy((*gensec_security)->mem_ctx);
- }
- gensec_security = NULL;
+ talloc_free(*gensec_security);
+ *gensec_security = NULL;
}
/**
gensec_security->want_features |= feature;
}
+/**
+ * Check the requirement for a certain feature on the connection
+ *
+ */
+
+BOOL gensec_have_feature(struct gensec_security *gensec_security,
+ uint32 feature)
+{
+ if (gensec_security->have_features & feature) {
+ return True;
+ }
+
+ return False;
+}
+
/**
* Set a username on a GENSEC context - ensures it is talloc()ed
*
NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, const char *user)
{
char *p;
- char *u = talloc_strdup(gensec_security->mem_ctx, user);
+ char *u = talloc_strdup(gensec_security, user);
if (!u) {
return NT_STATUS_NO_MEMORY;
}
if (p) {
*p = '\0';
- gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, u);
+ gensec_security->user.name = talloc_strdup(gensec_security, u);
if (!gensec_security->user.name) {
return NT_STATUS_NO_MEMORY;
}
- gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, p+1);
+ gensec_security->user.realm = talloc_strdup(gensec_security, p+1);
if (!gensec_security->user.realm) {
return NT_STATUS_NO_MEMORY;
}
if (p) {
*p = '\0';
- gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, u);
+ gensec_security->user.domain = talloc_strdup(gensec_security, u);
if (!gensec_security->user.domain) {
return NT_STATUS_NO_MEMORY;
}
- gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, p+1);
+ gensec_security->user.name = talloc_strdup(gensec_security, p+1);
if (!gensec_security->user.name) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user)
{
- gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, user);
+ gensec_security->user.name = talloc_strdup(gensec_security, user);
if (!gensec_security->user.name) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char *domain)
{
- gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, domain);
+ gensec_security->user.domain = talloc_strdup(gensec_security, domain);
if (!gensec_security->user.domain) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *realm)
{
- gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, realm);
+ gensec_security->user.realm = talloc_strdup(gensec_security, realm);
if (!gensec_security->user.realm) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_password(struct gensec_security *gensec_security,
const char *password)
{
- gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password);
+ gensec_security->user.password = talloc_strdup(gensec_security, password);
if (!gensec_security->user.password) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
{
- gensec_security->target.principal = talloc_strdup(gensec_security->mem_ctx, principal);
+ gensec_security->target.principal = talloc_strdup(gensec_security, principal);
if (!gensec_security->target.principal) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service)
{
- gensec_security->target.service = talloc_strdup(gensec_security->mem_ctx, service);
+ gensec_security->target.service = talloc_strdup(gensec_security, service);
if (!gensec_security->target.service) {
return NT_STATUS_NO_MEMORY;
}
NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname)
{
- gensec_security->target.hostname = talloc_strdup(gensec_security->mem_ctx, hostname);
+ gensec_security->target.hostname = talloc_strdup(gensec_security, hostname);
if (!gensec_security->target.hostname) {
return NT_STATUS_NO_MEMORY;
}
The 'name' can be later used by other backends to find the operations
structure for this backend.
*/
-static NTSTATUS gensec_register(const void *_ops)
+NTSTATUS gensec_register(const void *_ops)
{
const struct gensec_security_ops *ops = _ops;
+ if (!lp_parm_bool(-1, "gensec", ops->name, True)) {
+ DEBUG(2,("gensec subsystem %s is disabled\n", ops->name));
+ return NT_STATUS_OK;
+ }
+
if (gensec_security_by_name(ops->name) != NULL) {
/* its already registered! */
DEBUG(0,("GENSEC backend '%s' already registered\n",
return NT_STATUS_OBJECT_NAME_COLLISION;
}
- generic_security_ops = Realloc(generic_security_ops, sizeof(generic_security_ops[0]) * (gensec_num_backends+1));
+ generic_security_ops = realloc_p(generic_security_ops,
+ const struct gensec_security_ops *,
+ gensec_num_backends+1);
if (!generic_security_ops) {
smb_panic("out of memory in gensec_register");
}
/*
initialise the GENSEC subsystem
*/
-BOOL gensec_init(void)
+NTSTATUS gensec_init(void)
{
- static BOOL initialised;
- NTSTATUS status;
-
- /* this is *completely* the wrong way to do this */
- if (initialised) {
- return True;
- }
-
- status = register_subsystem("gensec", gensec_register);
- if (!NT_STATUS_IS_OK(status)) {
- return False;
- }
-
- static_init_gensec;
gensec_dcerpc_schannel_init();
-
- initialised = True;
- DEBUG(3,("GENSEC subsystem version %d initialised\n", GENSEC_INTERFACE_VERSION));
- return True;
+ return NT_STATUS_OK;
}