summaryrefslogtreecommitdiff
path: root/source4/auth/gensec/gensec.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-05-15 23:42:11 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:16:45 -0500
commit5c6dd5e800b879efdce3bbc3a16f32c5e78b4917 (patch)
tree13a8286bebac583bd979d278b7f12fac25c8513b /source4/auth/gensec/gensec.c
parent8f96c42027d282eec047d1b25951a33bc2fce71f (diff)
downloadsamba-5c6dd5e800b879efdce3bbc3a16f32c5e78b4917.tar.gz
samba-5c6dd5e800b879efdce3bbc3a16f32c5e78b4917.tar.bz2
samba-5c6dd5e800b879efdce3bbc3a16f32c5e78b4917.zip
r6800: A big GENSEC update:
Finally remove the distinction between 'krb5' and 'ms_krb5'. We now don't do kerberos stuff twice on failure. The solution to this is slightly more general than perhaps was really required (as this is a special case), but it works, and I'm happy with the cleanup I achived in the process. All modules have been updated to supply a NULL-terminated list of OIDs. In that process, SPNEGO code has been generalised, as I realised that two of the functions should have been identical in behaviour. Over in the actual modules, I have worked to remove the 'kinit' code from gensec_krb5, and placed it in kerberos/kerberos_util.c. The GSSAPI module has been extended to use this, so no longer requires a manual kinit at the command line. It will soon loose the requirement for a on-disk keytab too. The general kerberos code has also been updated to move from error_message() to our routine which gets the Heimdal error string (which may be much more useful) when available. Andrew Bartlett (This used to be commit 0101728d8e2ed9419eb31fe95047944a718ba135)
Diffstat (limited to 'source4/auth/gensec/gensec.c')
-rw-r--r--source4/auth/gensec/gensec.c147
1 files changed, 133 insertions, 14 deletions
diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c
index 77ba58fcde..1608f21114 100644
--- a/source4/auth/gensec/gensec.c
+++ b/source4/auth/gensec/gensec.c
@@ -42,11 +42,15 @@ static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t aut
static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string)
{
- int i;
+ int i, j;
for (i=0; i < gensec_num_backends; i++) {
- if (generic_security_ops[i]->oid &&
- (strcmp(generic_security_ops[i]->oid, oid_string) == 0)) {
- return generic_security_ops[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];
+ }
+ }
}
}
@@ -85,16 +89,99 @@ const struct gensec_security_ops **gensec_security_all(int *num_backends_out)
return generic_security_ops;
}
-const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip)
+/**
+ * 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 is in the exact order of the OIDs asked for, where available.
+ */
+
+const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX *mem_ctx,
+ const char **oid_strings,
+ const char *skip)
{
- int i, j = 0;
- const char **oid_list;
+ struct gensec_security_ops_wrapper *backends_out;
+ const struct gensec_security_ops **backends;
+ int i, j, k, oid_idx;
+ int num_backends_out = 0;
int num_backends;
- const struct gensec_security_ops **ops = gensec_security_all(&num_backends);
+
+ if (!oid_strings) {
+ return NULL;
+ }
+
+ backends = gensec_security_all(&num_backends);
+
+ backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
+ if (!backends_out) {
+ return NULL;
+ }
+ backends_out[0].op = NULL;
+ backends_out[0].oid = NULL;
+
+ for (oid_idx = 0; oid_strings[oid_idx]; oid_idx++) {
+ if (strcmp(oid_strings[oid_idx], skip) == 0) {
+ continue;
+ }
+
+ for (i=0; i < num_backends; i++) {
+ if (!backends[i]->oid) {
+ continue;
+ }
+ for (j=0; backends[i]->oid[j]; j++) {
+ if (!backends[i]->oid[j] ||
+ !(strcmp(backends[i]->oid[j],
+ oid_strings[oid_idx]) == 0)) {
+ continue;
+ }
+
+ for (k=0; backends_out[k].op; k++) {
+ if (backends_out[k].op == backends[i]) {
+ break;
+ }
+ }
+
+ if (k < num_backends_out) {
+ /* already in there */
+ continue;
+ }
+
+ backends_out = talloc_realloc(mem_ctx, backends_out,
+ struct gensec_security_ops_wrapper,
+ num_backends_out + 2);
+ if (!backends_out) {
+ return NULL;
+ }
+
+ backends_out[num_backends_out].op = backends[i];
+ backends_out[num_backends_out].oid = backends[i]->oid[j];
+ num_backends_out++;
+ backends_out[num_backends_out].op = NULL;
+ backends_out[num_backends_out].oid = NULL;
+ }
+ }
+ }
+ return backends_out;
+}
+
+/**
+ * Return OIDS from the security subsystems listed
+ */
+
+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;
+ int j = 0;
+ int k;
+ const char **oid_list;
if (!ops) {
return NULL;
}
- oid_list = talloc_array(mem_ctx, const char *, num_backends + 1);
+ oid_list = talloc_array(mem_ctx, const char *, 1);
if (!oid_list) {
return NULL;
}
@@ -104,17 +191,37 @@ const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip)
continue;
}
- if (skip && strcmp(skip, ops[i]->oid)==0) {
- continue;
+ for (k = 0; ops[i]->oid[k]; k++) {
+ if (skip && strcmp(skip, ops[i]->oid[k])==0) {
+ } else {
+ oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2);
+ if (!oid_list) {
+ return NULL;
+ }
+ oid_list[j] = ops[i]->oid[k];
+ j++;
+ }
}
-
- oid_list[j] = ops[i]->oid;
- j++;
}
oid_list[j] = NULL;
return oid_list;
}
+
+/**
+ * Return all the security subsystems currently enabled in GENSEC
+ */
+
+const char **gensec_security_oids(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);
+}
+
+
+
/**
Start the GENSEC system, returning a context pointer.
@param mem_ctx The parent TALLOC memory context.
@@ -284,6 +391,18 @@ const char *gensec_get_name_by_oid(const char *oid_string)
/**
+ * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO
+ *
+ */
+
+NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security,
+ const struct gensec_security_ops *ops)
+{
+ gensec_security->ops = ops;
+ return gensec_start_mech(gensec_security);
+}
+
+/**
* Start a GENSEC sub-mechanism by OID, used in SPNEGO
*
* @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a