diff options
-rw-r--r-- | source4/auth/credentials/config.mk | 7 | ||||
-rw-r--r-- | source4/auth/credentials/credentials.c | 1 | ||||
-rw-r--r-- | source4/auth/credentials/credentials.h | 3 | ||||
-rw-r--r-- | source4/auth/gensec/gensec.c | 144 | ||||
-rw-r--r-- | source4/auth/gensec/spnego.c | 15 |
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++) { |