diff options
author | Andrew Bartlett <abartlet@samba.org> | 2004-07-13 05:14:59 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:57:34 -0500 |
commit | ed03516c915c4a4c8ae6f7decfa04d51049d9dd5 (patch) | |
tree | 41f535a24108d59c367849ae80885198e371bda3 /source4/libcli/auth/gensec.c | |
parent | 39b12015846e06cbf89079e365e6c228ca3883c2 (diff) | |
download | samba-ed03516c915c4a4c8ae6f7decfa04d51049d9dd5.tar.gz samba-ed03516c915c4a4c8ae6f7decfa04d51049d9dd5.tar.bz2 samba-ed03516c915c4a4c8ae6f7decfa04d51049d9dd5.zip |
r1475: More kerberos work
- We can now connect to hosts that follow the SPNEGO RFC, and *do not*
give us their principal name in the mechListMIC.
- The client code now remembers the hostname it connects to
- We now kinit for a user, if there is not valid ticket already
- Re-introduce clock skew compensation
TODO:
- See if the username in the ccache matches the username specified
- Use a private ccache, rather then the global one, for a 'new' kinit
- Determine 'default' usernames.
- The default for Krb5 is the one in the ccache, then $USER
- For NTLMSSP, it's just $USER
Andrew Bartlett
(This used to be commit de5da669397db4ac87c6da08d3533ca3030da2b0)
Diffstat (limited to 'source4/libcli/auth/gensec.c')
-rw-r--r-- | source4/libcli/auth/gensec.c | 189 |
1 files changed, 181 insertions, 8 deletions
diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c index f4aeedf692..e91497bee4 100644 --- a/source4/libcli/auth/gensec.c +++ b/source4/libcli/auth/gensec.c @@ -106,6 +106,14 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security) (*gensec_security)->mem_ctx = mem_ctx; (*gensec_security)->ops = NULL; + ZERO_STRUCT((*gensec_security)->user); + ZERO_STRUCT((*gensec_security)->target); + 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)->subcontext = False; return NT_STATUS_OK; } @@ -163,6 +171,9 @@ NTSTATUS gensec_server_start(struct gensec_security **gensec_security) static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) { NTSTATUS status; + DEBUG(5, ("Starting GENSEC %smechanism %s\n", + gensec_security->subcontext ? "sub" : "", + gensec_security->ops->name)); switch (gensec_security->gensec_role) { case GENSEC_CLIENT: if (gensec_security->ops->client_start) { @@ -342,6 +353,61 @@ void gensec_end(struct gensec_security **gensec_security) * */ +NTSTATUS gensec_set_unparsed_username(struct gensec_security *gensec_security, const char *user) +{ + char *p; + char *u = talloc_strdup(gensec_security->mem_ctx, user); + if (!u) { + return NT_STATUS_NO_MEMORY; + } + + p = strchr_m(user, '@'); + + if (p) { + *p = '\0'; + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, u); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + + gensec_security->user.realm = talloc_strdup(gensec_security->mem_ctx, p+1); + if (!gensec_security->user.realm) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; + } + + p = strchr_m(user, '\\'); + if (!p) { + p = strchr_m(user, '/'); + } + + if (p) { + *p = '\0'; + gensec_security->user.domain = talloc_strdup(gensec_security->mem_ctx, u); + if (!gensec_security->user.domain) { + return NT_STATUS_NO_MEMORY; + } + gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, p+1); + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; + } + + gensec_security->user.name = u; + if (!gensec_security->user.name) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char *user) { gensec_security->user.name = talloc_strdup(gensec_security->mem_ctx, user); @@ -352,6 +418,19 @@ NTSTATUS gensec_set_username(struct gensec_security *gensec_security, const char } /** + * Set a username on a GENSEC context - ensures it is talloc()ed + * + */ + +const char *gensec_get_username(struct gensec_security *gensec_security) +{ + if (gensec_security->user.name) { + return gensec_security->user.name; + } + return gensec_security->default_user.name; +} + +/** * Set a domain on a GENSEC context - ensures it is talloc()ed * */ @@ -366,19 +445,18 @@ NTSTATUS gensec_set_domain(struct gensec_security *gensec_security, const char * } /** - * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will - * not do a callback + * Return the NT domain for this GENSEC context * */ -NTSTATUS gensec_set_password(struct gensec_security *gensec_security, - const char *password) +const char *gensec_get_domain(struct gensec_security *gensec_security) { - gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); - if (!gensec_security->user.password) { - return NT_STATUS_NO_MEMORY; + if (gensec_security->user.domain) { + return gensec_security->user.domain; + } else if (gensec_security->user.realm) { + return gensec_security->user.realm; } - return NT_STATUS_OK; + return gensec_security->default_user.domain; } /** @@ -396,6 +474,54 @@ NTSTATUS gensec_set_realm(struct gensec_security *gensec_security, const char *r } /** + * Return the Krb5 realm for this context + * + */ + +const char *gensec_get_realm(struct gensec_security *gensec_security) +{ + if (gensec_security->user.realm) { + return gensec_security->user.realm; + } else if (gensec_security->user.domain) { + return gensec_security->user.domain; + } + return gensec_security->default_user.realm; +} + +/** + * Return a kerberos principal for this context, if one has been set + * + */ + +char *gensec_get_client_principal(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) +{ + const char *realm = gensec_get_realm(gensec_security); + if (realm) { + return talloc_asprintf(mem_ctx, "%s@%s", + gensec_get_username(gensec_security), + gensec_get_realm(gensec_security)); + } else { + return talloc_strdup(mem_ctx, gensec_get_username(gensec_security)); + } +} + +/** + * Set the password outright on GENSEC context - ensures it is talloc()ed, and that we will + * not do a callback + * + */ + +NTSTATUS gensec_set_password(struct gensec_security *gensec_security, + const char *password) +{ + gensec_security->user.password = talloc_strdup(gensec_security->mem_ctx, password); + if (!gensec_security->user.password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** * Set the target principal name (if already known) on a GENSEC context - ensures it is talloc()ed * */ @@ -410,6 +536,53 @@ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, co } /** + * Set the target service (such as 'http' or 'host') on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_target_service(struct gensec_security *gensec_security, const char *service) +{ + gensec_security->target.service = talloc_strdup(gensec_security->mem_ctx, service); + if (!gensec_security->target.service) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set the target hostname (suitable for kerberos resolutation) on a GENSEC context - ensures it is talloc()ed + * + */ + +NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_security, const char *hostname) +{ + gensec_security->target.hostname = talloc_strdup(gensec_security->mem_ctx, hostname); + if (!gensec_security->target.hostname) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +const char *gensec_get_target_hostname(struct gensec_security *gensec_security) +{ + if (gensec_security->target.hostname) { + return gensec_security->target.hostname; + } + + /* TODO: Add a 'set sockaddr' call, and do a reverse lookup */ + return NULL; +} + +const char *gensec_get_target_service(struct gensec_security *gensec_security) +{ + if (gensec_security->target.service) { + return gensec_security->target.service; + } + + return "host"; +} + +/** * Set a password callback, if the gensec module we use demands a password */ |