summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-12-05 03:20:40 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:47:02 -0500
commit61bd60957418b872688dc22ec41f7a7ec4f267b2 (patch)
tree33fdeea53b9aafa01b91a56ca24451e674767e49
parent42f2bfbd9b13f0abec00d046f5e0b60fcaf343ef (diff)
downloadsamba-61bd60957418b872688dc22ec41f7a7ec4f267b2.tar.gz
samba-61bd60957418b872688dc22ec41f7a7ec4f267b2.tar.bz2
samba-61bd60957418b872688dc22ec41f7a7ec4f267b2.zip
r12060: Work towards allowing the credentials system to allow/deny certain
GENSEC mechansims. This will allow a machine join to an NT4 domain to avoid even trying kerberos, or a sensitive operation to require it. Andrew Bartlett (This used to be commit 11c7a89e523f85afd728d5e5f03bb084dc620244)
-rw-r--r--source4/auth/credentials/config.mk7
-rw-r--r--source4/auth/credentials/credentials.c1
-rw-r--r--source4/auth/credentials/credentials.h3
-rw-r--r--source4/auth/gensec/gensec.c144
-rw-r--r--source4/auth/gensec/spnego.c15
5 files changed, 105 insertions, 65 deletions
diff --git a/source4/auth/credentials/config.mk b/source4/auth/credentials/config.mk
index 5e3299784e..00d8319739 100644
--- a/source4/auth/credentials/config.mk
+++ b/source4/auth/credentials/config.mk
@@ -4,9 +4,10 @@
INIT_OBJ_FILES = credentials.o
ADD_OBJ_FILES = credentials_files.o \
credentials_krb5.o \
- credentials_ntlm.o
+ credentials_ntlm.o \
+ credentials_gensec.o
REQUIRED_SUBSYSTEMS = \
- HEIMDAL
-# End SUBSYSTEM GENSEC
+ HEIMDAL GENSEC
+# End SUBSYSTEM CREDENTIALS
#################################
diff --git a/source4/auth/credentials/credentials.c b/source4/auth/credentials/credentials.c
index 75c6795e73..22b7772182 100644
--- a/source4/auth/credentials/credentials.c
+++ b/source4/auth/credentials/credentials.c
@@ -55,6 +55,7 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
cred->smb_krb5_context = NULL;
cred->salt_principal = NULL;
cred->machine_account = False;
+ cred->gensec_list = NULL;
return cred;
}
diff --git a/source4/auth/credentials/credentials.h b/source4/auth/credentials/credentials.h
index 81773aa70a..ec6f1aa619 100644
--- a/source4/auth/credentials/credentials.h
+++ b/source4/auth/credentials/credentials.h
@@ -91,4 +91,7 @@ struct cli_credentials {
/* Is this a machine account? */
BOOL machine_account;
+
+ /* A list of valid GENSEC mechanisms for use on this account */
+ struct gensec_security_ops **gensec_list;
};
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c
index a23846f3ad..0d79cb892c 100644
--- a/source4/auth/gensec/gensec.c
+++ b/source4/auth/gensec/gensec.c
@@ -29,27 +29,46 @@
const static struct gensec_security_ops **generic_security_ops;
static int gensec_num_backends;
-static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type)
+const struct gensec_security_ops **gensec_security_all(void)
+{
+ return generic_security_ops;
+}
+
+static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security,
+ uint8_t auth_type)
{
int i;
- for (i=0; i < gensec_num_backends; i++) {
- if (generic_security_ops[i]->auth_type == auth_type) {
- return generic_security_ops[i];
+ const struct gensec_security_ops **backends;
+ if (!gensec_security) {
+ backends = gensec_security_all();
+ } else {
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ }
+ for (i=0; backends && backends[i]; i++) {
+ if (backends[i]->auth_type == auth_type) {
+ return backends[i];
}
}
return NULL;
}
-static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string)
+static const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security *gensec_security,
+ const char *oid_string)
{
int i, j;
- for (i=0; i < gensec_num_backends; i++) {
- if (generic_security_ops[i]->oid) {
- for (j=0; generic_security_ops[i]->oid[j]; j++) {
- if (generic_security_ops[i]->oid[j] &&
- (strcmp(generic_security_ops[i]->oid[j], oid_string) == 0)) {
- return generic_security_ops[i];
+ const struct gensec_security_ops **backends;
+ if (!gensec_security) {
+ backends = gensec_security_all();
+ } else {
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ }
+ for (i=0; backends && backends[i]; i++) {
+ if (backends[i]->oid) {
+ for (j=0; backends[i]->oid[j]; j++) {
+ if (backends[i]->oid[j] &&
+ (strcmp(backends[i]->oid[j], oid_string) == 0)) {
+ return backends[i];
}
}
}
@@ -58,60 +77,68 @@ static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_
return NULL;
}
-static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name)
+static const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_security *gensec_security,
+ const char *sasl_name)
{
int i;
- for (i=0; i < gensec_num_backends; i++) {
- if (generic_security_ops[i]->sasl_name
- && (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) {
- return generic_security_ops[i];
+ const struct gensec_security_ops **backends;
+ if (!gensec_security) {
+ backends = gensec_security_all();
+ } else {
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ }
+ for (i=0; backends && backends[i]; i++) {
+ if (backends[i]->sasl_name
+ && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
+ return backends[i];
}
}
return NULL;
}
-static const struct gensec_security_ops *gensec_security_by_name(const char *name)
+static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security,
+ const char *name)
{
int i;
- for (i=0; i < gensec_num_backends; i++) {
- if (generic_security_ops[i]->name
- && (strcmp(generic_security_ops[i]->name, name) == 0)) {
- return generic_security_ops[i];
+ const struct gensec_security_ops **backends;
+ if (!gensec_security) {
+ backends = gensec_security_all();
+ } else {
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ }
+ for (i=0; backends && backends[i]; i++) {
+ if (backends[i]->name
+ && (strcmp(backends[i]->name, name) == 0)) {
+ return backends[i];
}
}
return NULL;
}
-const struct gensec_security_ops **gensec_security_all(int *num_backends_out)
-{
- *num_backends_out = gensec_num_backends;
- return generic_security_ops;
-}
-
/**
* Return a unique list of security subsystems from those specified in
- * the OID list. That is, where two OIDs refer to the same module,
- * return that module only once
+ * the list of SASL names.
*
- * The list is in the exact order of the OIDs asked for, where available.
+ * Use the list of enabled GENSEC mechanisms from the credentials
+ * attached to the gensec_security, and return in our preferred order.
*/
-const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
- const char **sasl_names)
+const struct gensec_security_ops **gensec_security_by_sasl(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx,
+ const char **sasl_names)
{
const struct gensec_security_ops **backends_out;
const struct gensec_security_ops **backends;
int i, k, sasl_idx;
int num_backends_out = 0;
- int num_backends;
if (!sasl_names) {
return NULL;
}
- backends = gensec_security_all(&num_backends);
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
if (!backends_out) {
@@ -121,7 +148,7 @@ const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
/* Find backends in our preferred order, by walking our list,
* then looking in the supplied list */
- for (i=0; i < num_backends; i++) {
+ for (i=0; backends && backends[i]; i++) {
for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) {
if (!backends[i]->sasl_name ||
!(strcmp(backends[i]->sasl_name,
@@ -158,12 +185,14 @@ const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
/**
* Return a unique list of security subsystems from those specified in
* the OID list. That is, where two OIDs refer to the same module,
- * return that module only once
+ * return that module only once.
*
- * The list is in the exact order of the OIDs asked for, where available.
+ * Use the list of enabled GENSEC mechanisms from the credentials
+ * attached to the gensec_security, and return in our preferred order.
*/
-const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX *mem_ctx,
+const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx,
const char **oid_strings,
const char *skip)
{
@@ -171,13 +200,12 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
const struct gensec_security_ops **backends;
int i, j, k, oid_idx;
int num_backends_out = 0;
- int num_backends;
if (!oid_strings) {
return NULL;
}
- backends = gensec_security_all(&num_backends);
+ backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
if (!backends_out) {
@@ -188,7 +216,7 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
/* Find backends in our preferred order, by walking our list,
* then looking in the supplied list */
- for (i=0; i < num_backends; i++) {
+ for (i=0; backends && backends[i]; i++) {
if (!backends[i]->oid) {
continue;
}
@@ -239,7 +267,6 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx,
const struct gensec_security_ops **ops,
- int num_backends,
const char *skip)
{
int i;
@@ -254,7 +281,7 @@ const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx,
return NULL;
}
- for (i=0; i<num_backends; i++) {
+ for (i=0; ops && ops[i]; i++) {
if (!ops[i]->oid) {
continue;
}
@@ -315,15 +342,20 @@ const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX *mem_ctx,
/**
- * Return all the security subsystems currently enabled in GENSEC
+ * Return all the security subsystems currently enabled on a GENSEC context.
+ *
+ * This is taken from a list attached to the cli_credentails, and
+ * skips the OID in 'skip'. (Typically the SPNEGO OID)
+ *
*/
-const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip)
+const char **gensec_security_oids(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx,
+ const char *skip)
{
- int num_backends;
- const struct gensec_security_ops **ops = gensec_security_all(&num_backends);
- return gensec_security_oids_from_ops(mem_ctx, ops,
- num_backends, skip);
+ const struct gensec_security_ops **ops
+ = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ return gensec_security_oids_from_ops(mem_ctx, ops, skip);
}
@@ -465,7 +497,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security)
NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
uint8_t auth_type, uint8_t auth_level)
{
- gensec_security->ops = gensec_security_by_authtype(auth_type);
+ gensec_security->ops = gensec_security_by_authtype(gensec_security, auth_type);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
return NT_STATUS_INVALID_PARAMETER;
@@ -491,7 +523,7 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
const char *gensec_get_name_by_authtype(uint8_t authtype)
{
const struct gensec_security_ops *ops;
- ops = gensec_security_by_authtype(authtype);
+ ops = gensec_security_by_authtype(NULL, authtype);
if (ops) {
return ops->name;
}
@@ -502,7 +534,7 @@ const char *gensec_get_name_by_authtype(uint8_t authtype)
const char *gensec_get_name_by_oid(const char *oid_string)
{
const struct gensec_security_ops *ops;
- ops = gensec_security_by_oid(oid_string);
+ ops = gensec_security_by_oid(NULL, oid_string);
if (ops) {
return ops->name;
}
@@ -532,7 +564,7 @@ NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
const char *mech_oid)
{
- gensec_security->ops = gensec_security_by_oid(mech_oid);
+ gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid));
return NT_STATUS_INVALID_PARAMETER;
@@ -548,7 +580,7 @@ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
const char *sasl_name)
{
- gensec_security->ops = gensec_security_by_sasl_name(sasl_name);
+ gensec_security->ops = gensec_security_by_sasl_name(gensec_security, sasl_name);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name));
return NT_STATUS_INVALID_PARAMETER;
@@ -564,7 +596,7 @@ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
const char *name)
{
- gensec_security->ops = gensec_security_by_name(name);
+ gensec_security->ops = gensec_security_by_name(gensec_security, name);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name));
return NT_STATUS_INVALID_PARAMETER;
@@ -862,7 +894,7 @@ NTSTATUS gensec_register(const void *_ops)
return NT_STATUS_OK;
}
- if (gensec_security_by_name(ops->name) != NULL) {
+ if (gensec_security_by_name(NULL, ops->name) != NULL) {
/* its already registered! */
DEBUG(0,("GENSEC backend '%s' already registered\n",
ops->name));
diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c
index b7fba789b1..6e4ee4b558 100644
--- a/source4/auth/gensec/spnego.c
+++ b/source4/auth/gensec/spnego.c
@@ -247,9 +247,9 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec
const DATA_BLOB in, DATA_BLOB *out)
{
int i,j;
- int num_ops;
- const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops);
- for (i=0; i < num_ops; i++) {
+ const struct gensec_security_ops **all_ops
+ = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
+ for (i=0; all_ops[i]; i++) {
BOOL is_spnego;
NTSTATUS nt_status;
if (!all_ops[i]->oid) {
@@ -315,7 +315,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
DATA_BLOB null_data_blob = data_blob(NULL,0);
const struct gensec_security_ops_wrapper *all_sec
- = gensec_security_by_oid_list(out_mem_ctx,
+ = gensec_security_by_oid_list(gensec_security,
+ out_mem_ctx,
mechType,
GENSEC_OID_SPNEGO);
for (i=0; all_sec && all_sec[i].op; i++) {
@@ -413,9 +414,11 @@ static NTSTATUS gensec_spnego_create_negTokenInit(struct gensec_security *gensec
const struct gensec_security_ops_wrapper *all_sec;
const char *principal = NULL;
- mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO);
+ mechTypes = gensec_security_oids(gensec_security,
+ out_mem_ctx, GENSEC_OID_SPNEGO);
- all_sec = gensec_security_by_oid_list(out_mem_ctx,
+ all_sec = gensec_security_by_oid_list(gensec_security,
+ out_mem_ctx,
mechTypes,
GENSEC_OID_SPNEGO);
for (i=0; all_sec && all_sec[i].op; i++) {