summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-08-04 14:42:37 -0400
committerSimo Sorce <simo@redhat.com>2014-08-07 12:44:46 -0400
commitea3853bc1146299617e334592c0bbd25ad33376c (patch)
tree2cd0428a50d8a036e2b8667af03b3aa1f8b4d03d
parent593fc9ad0c06f737c97d5e240fe70e2508c164d4 (diff)
downloadgss-ntlmssp-ea3853bc1146299617e334592c0bbd25ad33376c.tar.gz
gss-ntlmssp-ea3853bc1146299617e334592c0bbd25ad33376c.tar.xz
gss-ntlmssp-ea3853bc1146299617e334592c0bbd25ad33376c.zip
Use helpers to get the local netbios names
move out fetching of the computer and domain netbios names. Names are still fetched from environment variables, or external sources (like winbind) or defaults are used. Based on work from David Woodhouse.
-rw-r--r--src/external.c5
-rw-r--r--src/gss_names.c78
-rw-r--r--src/gss_ntlmssp.h5
-rw-r--r--src/gss_sec_ctx.c91
4 files changed, 125 insertions, 54 deletions
diff --git a/src/external.c b/src/external.c
index 11dcec8..07bbaab 100644
--- a/src/external.c
+++ b/src/external.c
@@ -3,6 +3,11 @@
#include <errno.h>
#include "gss_ntlmssp.h"
+uint32_t external_netbios_get_names(char **computer, char **domain)
+{
+ return ENOSYS;
+}
+
uint32_t external_get_creds(struct gssntlm_name *name,
struct gssntlm_cred *cred)
{
diff --git a/src/gss_names.c b/src/gss_names.c
index f48d117..e25c707 100644
--- a/src/gss_names.c
+++ b/src/gss_names.c
@@ -17,6 +17,7 @@
#define _GNU_SOURCE
+#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <pwd.h>
@@ -529,3 +530,80 @@ done:
localname->length = strlen(uname) + 1;
return GSS_S_COMPLETE;
}
+
+uint32_t netbios_get_names(char *computer_name,
+ char **netbios_host, char **netbios_domain)
+{
+ char *nb_computer_name = NULL;
+ char *nb_domain_name = NULL;
+ char *env_name;
+ uint32_t ret;
+
+ env_name = getenv("NETBIOS_COMPUTER_NAME");
+ if (env_name) {
+ nb_computer_name = strdup(env_name);
+ if (!nb_computer_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ env_name = getenv("NETBIOS_DOMAIN_NAME");
+ if (env_name) {
+ nb_domain_name = strdup(env_name);
+ if (!nb_domain_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ if (!nb_computer_name || !nb_domain_name) {
+ /* fetch only missing ones */
+ ret = external_netbios_get_names(
+ nb_computer_name ? NULL : &nb_computer_name,
+ nb_domain_name ? NULL : &nb_domain_name);
+ if ((ret != 0) &&
+ (ret != ENOENT) &&
+ (ret != ENOSYS)) {
+ goto done;
+ }
+ }
+
+ if (!nb_computer_name) {
+ char *p;
+ p = strchr(computer_name, '.');
+ if (p) {
+ nb_computer_name = strndup(computer_name, p - computer_name);
+ } else {
+ nb_computer_name = strdup(computer_name);
+ }
+ for (p = nb_computer_name; p && *p; p++) {
+ /* Can only be ASCII, so toupper is safe */
+ *p = toupper(*p);
+ }
+ if (!nb_computer_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ if (!nb_domain_name) {
+ nb_domain_name = strdup("WORKGROUP");
+ if (!nb_domain_name) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ ret = 0;
+
+done:
+ if (ret) {
+ safefree(nb_computer_name);
+ safefree(nb_domain_name);
+ }
+
+ *netbios_domain = nb_domain_name;
+ *netbios_host = nb_computer_name;
+ return ret;
+}
diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h
index 887138f..7d45d41 100644
--- a/src/gss_ntlmssp.h
+++ b/src/gss_ntlmssp.h
@@ -168,7 +168,7 @@ void gssntlm_int_release_cred(struct gssntlm_cred *cred);
int gssntlm_copy_name(struct gssntlm_name *src, struct gssntlm_name *dst);
int gssntlm_copy_creds(struct gssntlm_cred *in, struct gssntlm_cred *out);
-
+uint32_t external_netbios_get_names(char **computer, char **domain);
uint32_t external_get_creds(struct gssntlm_name *name,
struct gssntlm_cred *cred);
uint32_t external_srv_auth(char *user, char *domain,
@@ -177,6 +177,9 @@ uint32_t external_srv_auth(char *user, char *domain,
struct ntlm_buffer *lm_chal_resp,
struct ntlm_key *ntlmv2_key);
+uint32_t netbios_get_names(char *computer_name,
+ char **netbios_host, char **netbios_domain);
+
uint32_t gssntlm_srv_auth(uint32_t *minor,
struct gssntlm_ctx *ctx,
struct gssntlm_cred *cred,
diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c
index 89972e6..265d24e 100644
--- a/src/gss_sec_ctx.c
+++ b/src/gss_sec_ctx.c
@@ -15,7 +15,6 @@
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -41,8 +40,10 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
struct gssntlm_ctx *ctx;
struct gssntlm_name *server = NULL;
struct gssntlm_cred *cred = NULL;
- char *env_name;
- char *workstation = NULL;
+ char *computer_name = NULL;
+ char *nb_computer_name = NULL;
+ char *nb_domain_name = NULL;
+ struct gssntlm_name *client_name = NULL;
const char *domain = NULL;
uint32_t in_flags;
uint32_t msg_type;
@@ -185,40 +186,41 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
domain = cred->cred.user.user.data.user.domain;
}
- env_name = getenv("NETBIOS_COMPUTER_NAME");
- if (env_name) {
- workstation = strdup(env_name);
- } else {
/* acquire our own name */
- gss_buffer_desc tmpbuf = { 0, discard_const("") };
- struct gssntlm_name *tmpname;
- char *p;
+ if (!client_name) {
+ gss_buffer_desc tmpbuf;
+ tmpbuf.value = discard_const("");
+ tmpbuf.length = 0;
retmaj = gssntlm_import_name_by_mech(&retmin,
&gssntlm_oid,
&tmpbuf,
GSS_C_NT_HOSTBASED_SERVICE,
- (gss_name_t *)&tmpname);
+ (gss_name_t *)&client_name);
if (retmaj) goto done;
- p = strchr(tmpname->data.server.name, '.');
- if (p) {
- workstation = strndup(tmpname->data.server.name,
- p - tmpname->data.server.name);
- } else {
- workstation = strdup(tmpname->data.server.name);
- }
- for (p = workstation; p && *p; p++) {
- /* Can only be ASCII, so toupper is safe */
- *p = toupper(*p);
- }
- gssntlm_release_name(&tmpmin, (gss_name_t *)&tmpname);
}
- if (!workstation) {
+
+ computer_name = strdup(client_name->data.server.name);
+ if (!computer_name) {
retmin = ENOMEM;
retmaj = GSS_S_FAILURE;
goto done;
}
+
+ retmin = netbios_get_names(computer_name,
+ &nb_computer_name, &nb_domain_name);
+ if (retmin) {
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
+ ctx->workstation = strdup(nb_computer_name);
+ if (!ctx->workstation) {
+ retmin = ENOMEM;
+ retmaj = GSS_S_FAILURE;
+ goto done;
+ }
+
ctx->neg_flags |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
- ctx->workstation = workstation;
lm_compat_lvl = gssntlm_get_lm_compatibility_level();
sec_req = gssntlm_required_security(lm_compat_lvl, ctx->role);
@@ -266,7 +268,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
}
retmin = ntlm_encode_neg_msg(ctx->ntlm, ctx->neg_flags,
- domain, workstation, &ctx->nego_msg);
+ domain, ctx->workstation, &ctx->nego_msg);
if (retmin) {
retmaj = GSS_S_FAILURE;
goto done;
@@ -694,6 +696,10 @@ done:
/* do not leak it, if not passed in */
gssntlm_release_cred(&tmpmin, (gss_cred_id_t *)&cred);
}
+ gssntlm_release_name(&tmpmin, (gss_name_t *)&client_name);
+ safefree(computer_name);
+ safefree(nb_computer_name);
+ safefree(nb_domain_name);
safefree(trgt_name);
ntlm_free_buffer_data(&client_target_info);
ntlm_free_buffer_data(&target_info);
@@ -787,9 +793,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
char *computer_name = NULL;
char *nb_computer_name = NULL;
char *nb_domain_name = NULL;
- char *env_name;
char *chal_target_name;
- gss_buffer_desc tmpbuf;
uint64_t timestamp;
struct ntlm_buffer target_info = { 0 };
struct ntlm_buffer nt_chal_resp = { 0 };
@@ -813,7 +817,6 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
struct ntlm_buffer unhashed_cb = { 0 };
struct ntlm_buffer av_cb = { 0 };
uint8_t sec_req;
- char *p;
if (context_handle == NULL) return GSS_S_CALL_INACCESSIBLE_READ;
if (output_token == GSS_C_NO_BUFFER) {
@@ -963,6 +966,7 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
/* acquire our own name */
if (!server_name) {
+ gss_buffer_desc tmpbuf;
tmpbuf.value = discard_const("");
tmpbuf.length = 0;
retmaj = gssntlm_import_name_by_mech(&retmin,
@@ -986,34 +990,15 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
goto done;
}
- env_name = getenv("NETBIOS_COMPUTER_NAME");
- if (env_name) {
- nb_computer_name = strdup(env_name);
- } else {
- p = strchr(computer_name, '.');
- if (p) {
- nb_computer_name = strndup(computer_name, p - computer_name);
- } else {
- nb_computer_name = strdup(computer_name);
- }
- for (p = nb_computer_name; p && *p; p++) {
- /* Can only be ASCII, so toupper is safe */
- *p = toupper(*p);
- }
- }
- if (!nb_computer_name) {
- retmin = ENOMEM;
+ retmin = netbios_get_names(computer_name,
+ &nb_computer_name, &nb_domain_name);
+ if (retmin) {
retmaj = GSS_S_FAILURE;
goto done;
}
- env_name = getenv("NETBIOS_DOMAIN_NAME");
- if (env_name) {
- nb_domain_name = strdup(env_name);
- } else {
- nb_domain_name = strdup("WORKGROUP");
- }
- if (!nb_domain_name) {
+ ctx->workstation = strdup(nb_computer_name);
+ if (!ctx->workstation) {
retmin = ENOMEM;
retmaj = GSS_S_FAILURE;
goto done;