mirror of
https://github.com/samba-team/samba.git
synced 2025-11-25 00:23:52 +03:00
r13206: This patch finally re-adds a -k option that works reasonably.
From here we can add tests to Samba for kerberos, forcing it on and off. In the process, I also remove the dependency of credentials on GENSEC. This also picks up on the idea of bringing 'set_boolean' into general code from jpeach's cifsdd patch. Andrew Bartlett
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
78d634047f
commit
1ac7976ea6
@@ -5,10 +5,9 @@ PRIVATE_PROTO_HEADER = credentials_proto.h
|
|||||||
OBJ_FILES = credentials.o \
|
OBJ_FILES = credentials.o \
|
||||||
credentials_files.o \
|
credentials_files.o \
|
||||||
credentials_krb5.o \
|
credentials_krb5.o \
|
||||||
credentials_ntlm.o \
|
credentials_ntlm.o
|
||||||
credentials_gensec.o
|
|
||||||
REQUIRED_SUBSYSTEMS = \
|
REQUIRED_SUBSYSTEMS = \
|
||||||
HEIMDAL GENSEC LIBCLI_AUTH LIBLDB SECRETS
|
HEIMDAL LIBCLI_AUTH LIBLDB SECRETS
|
||||||
# End SUBSYSTEM CREDENTIALS
|
# End SUBSYSTEM CREDENTIALS
|
||||||
#################################
|
#################################
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "librpc/gen_ndr/ndr_samr.h" /* for struct samrPassword */
|
#include "librpc/gen_ndr/ndr_samr.h" /* for struct samrPassword */
|
||||||
|
#include "auth/gensec/gensec.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new credentials structure
|
* Create a new credentials structure
|
||||||
@@ -54,13 +54,26 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
|
|||||||
cred->smb_krb5_context = NULL;
|
cred->smb_krb5_context = NULL;
|
||||||
cred->salt_principal = NULL;
|
cred->salt_principal = NULL;
|
||||||
cred->machine_account = False;
|
cred->machine_account = False;
|
||||||
cred->gensec_list = NULL;
|
|
||||||
|
|
||||||
cred->bind_dn = NULL;
|
cred->bind_dn = NULL;
|
||||||
|
|
||||||
|
cli_credentials_set_kerberos_state(cred, CRED_AUTO_USE_KERBEROS);
|
||||||
|
|
||||||
return cred;
|
return cred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cli_credentials_set_kerberos_state(struct cli_credentials *creds,
|
||||||
|
enum credentials_use_kerberos use_kerberos)
|
||||||
|
{
|
||||||
|
creds->use_kerberos = use_kerberos;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds)
|
||||||
|
{
|
||||||
|
return creds->use_kerberos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain the username for this credentials context.
|
* Obtain the username for this credentials context.
|
||||||
* @param cred credentials context
|
* @param cred credentials context
|
||||||
|
|||||||
@@ -32,15 +32,19 @@ enum credentials_obtained {
|
|||||||
CRED_SPECIFIED /* Was explicitly specified on the command-line */
|
CRED_SPECIFIED /* Was explicitly specified on the command-line */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum credentials_use_kerberos {
|
||||||
|
CRED_AUTO_USE_KERBEROS = 0, /* Default, we try kerberos if available */
|
||||||
|
CRED_DONT_USE_KERBEROS, /* Sometimes trying kerberos just does 'bad things', so don't */
|
||||||
|
CRED_MUST_USE_KERBEROS /* Sometimes administrators are parinoid, so always do kerberos */
|
||||||
|
};
|
||||||
|
|
||||||
#define CLI_CRED_NTLM2 0x01
|
#define CLI_CRED_NTLM2 0x01
|
||||||
#define CLI_CRED_NTLMv2_AUTH 0x02
|
#define CLI_CRED_NTLMv2_AUTH 0x02
|
||||||
#define CLI_CRED_LANMAN_AUTH 0x04
|
#define CLI_CRED_LANMAN_AUTH 0x04
|
||||||
#define CLI_CRED_NTLM_AUTH 0x08
|
#define CLI_CRED_NTLM_AUTH 0x08
|
||||||
|
#define CLI_CRED_CLEAR_AUTH 0x10 /* TODO: Push cleartext auth with this flag */
|
||||||
|
|
||||||
struct cli_credentials {
|
struct cli_credentials {
|
||||||
/* Preferred methods, NULL means default */
|
|
||||||
const char **preferred_methods;
|
|
||||||
|
|
||||||
enum credentials_obtained workstation_obtained;
|
enum credentials_obtained workstation_obtained;
|
||||||
enum credentials_obtained username_obtained;
|
enum credentials_obtained username_obtained;
|
||||||
enum credentials_obtained password_obtained;
|
enum credentials_obtained password_obtained;
|
||||||
@@ -94,8 +98,8 @@ struct cli_credentials {
|
|||||||
/* Is this a machine account? */
|
/* Is this a machine account? */
|
||||||
BOOL machine_account;
|
BOOL machine_account;
|
||||||
|
|
||||||
/* A list of valid GENSEC mechanisms for use on this account */
|
/* Should we be trying to use kerberos? */
|
||||||
const struct gensec_security_ops **gensec_list;
|
enum credentials_use_kerberos use_kerberos;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "auth/credentials/credentials_proto.h"
|
#include "auth/credentials/credentials_proto.h"
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/CIFS implementation.
|
|
||||||
|
|
||||||
User credentials handling
|
|
||||||
|
|
||||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
#include "auth/gensec/gensec.h"
|
|
||||||
|
|
||||||
const struct gensec_security_ops **cli_credentials_gensec_list(struct cli_credentials *creds)
|
|
||||||
{
|
|
||||||
if (!creds || !creds->gensec_list) {
|
|
||||||
return gensec_security_all();
|
|
||||||
}
|
|
||||||
return creds->gensec_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static NTSTATUS cli_credentials_gensec_remove_mech(struct cli_credentials *creds,
|
|
||||||
const struct gensec_security_ops *remove_mech)
|
|
||||||
{
|
|
||||||
const struct gensec_security_ops **gensec_list;
|
|
||||||
const struct gensec_security_ops **new_gensec_list;
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
gensec_list = cli_credentials_gensec_list(creds);
|
|
||||||
|
|
||||||
for (i=0; gensec_list && gensec_list[i]; i++) {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
|
|
||||||
new_gensec_list = talloc_array(creds, const struct gensec_security_ops *, i + 1);
|
|
||||||
if (!new_gensec_list) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
for (i=0; gensec_list && gensec_list[i]; i++) {
|
|
||||||
if (gensec_list[i] != remove_mech) {
|
|
||||||
new_gensec_list[j] = gensec_list[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_gensec_list[j] = NULL;
|
|
||||||
|
|
||||||
creds->gensec_list = new_gensec_list;
|
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS cli_credentials_gensec_remove_oid(struct cli_credentials *creds,
|
|
||||||
const char *oid)
|
|
||||||
{
|
|
||||||
const struct gensec_security_ops *gensec_by_oid;
|
|
||||||
|
|
||||||
gensec_by_oid = gensec_security_by_oid(NULL, oid);
|
|
||||||
if (!gensec_by_oid) {
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli_credentials_gensec_remove_mech(creds, gensec_by_oid);
|
|
||||||
}
|
|
||||||
@@ -66,6 +66,10 @@ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_
|
|||||||
if (cred->machine_account) {
|
if (cred->machine_account) {
|
||||||
*flags = *flags & ~CLI_CRED_LANMAN_AUTH;
|
*flags = *flags & ~CLI_CRED_LANMAN_AUTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cred->use_kerberos == CRED_MUST_USE_KERBEROS) {
|
||||||
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
if (!nt_hash) {
|
if (!nt_hash) {
|
||||||
static const uint8_t zeros[16];
|
static const uint8_t zeros[16];
|
||||||
|
|||||||
@@ -27,29 +27,110 @@
|
|||||||
#include "smb_build.h"
|
#include "smb_build.h"
|
||||||
|
|
||||||
/* the list of currently registered GENSEC backends */
|
/* the list of currently registered GENSEC backends */
|
||||||
const static struct gensec_security_ops **generic_security_ops;
|
static struct gensec_security_ops **generic_security_ops;
|
||||||
static int gensec_num_backends;
|
static int gensec_num_backends;
|
||||||
|
|
||||||
const struct gensec_security_ops **gensec_security_all(void)
|
/* Return all the registered mechs. Don't modify the return pointer,
|
||||||
|
* but you may talloc_reference it if convient */
|
||||||
|
struct gensec_security_ops **gensec_security_all(void)
|
||||||
{
|
{
|
||||||
return generic_security_ops;
|
return generic_security_ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sometimes we want to force only kerberos, sometimes we want to
|
||||||
|
* force it's avoidance. The old list could be either
|
||||||
|
* gensec_security_all(), or from cli_credentials_gensec_list() (ie,
|
||||||
|
* an existing list we have trimmed down) */
|
||||||
|
|
||||||
|
struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx,
|
||||||
|
struct gensec_security_ops **old_gensec_list,
|
||||||
|
enum credentials_use_kerberos use_kerberos)
|
||||||
|
{
|
||||||
|
struct gensec_security_ops **new_gensec_list;
|
||||||
|
int i, j, num_mechs_in;
|
||||||
|
|
||||||
|
if (use_kerberos == CRED_AUTO_USE_KERBEROS) {
|
||||||
|
talloc_reference(mem_ctx, old_gensec_list);
|
||||||
|
return old_gensec_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) {
|
||||||
|
/* noop */
|
||||||
|
}
|
||||||
|
|
||||||
|
new_gensec_list = talloc_array(mem_ctx, struct gensec_security_ops *, num_mechs_in + 1);
|
||||||
|
if (!new_gensec_list) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for (i=0; old_gensec_list && old_gensec_list[i]; i++) {
|
||||||
|
int oid_idx;
|
||||||
|
for (oid_idx = 0; old_gensec_list[i]->oid && old_gensec_list[i]->oid[oid_idx]; oid_idx++) {
|
||||||
|
if (strcmp(old_gensec_list[i]->oid[oid_idx], GENSEC_OID_SPNEGO) == 0) {
|
||||||
|
new_gensec_list[j] = old_gensec_list[i];
|
||||||
|
j++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (use_kerberos) {
|
||||||
|
case CRED_DONT_USE_KERBEROS:
|
||||||
|
if (old_gensec_list[i]->kerberos == False) {
|
||||||
|
new_gensec_list[j] = old_gensec_list[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CRED_MUST_USE_KERBEROS:
|
||||||
|
if (old_gensec_list[i]->kerberos == True) {
|
||||||
|
new_gensec_list[j] = old_gensec_list[i];
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CRED_AUTO_USE_KERBEROS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_gensec_list[j] = NULL;
|
||||||
|
|
||||||
|
return new_gensec_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gensec_security_ops **gensec_security_mechs(struct gensec_security *gensec_security,
|
||||||
|
TALLOC_CTX *mem_ctx)
|
||||||
|
{
|
||||||
|
struct gensec_security_ops **backends;
|
||||||
|
backends = gensec_security_all();
|
||||||
|
if (!gensec_security) {
|
||||||
|
talloc_reference(mem_ctx, backends);
|
||||||
|
return backends;
|
||||||
|
} else {
|
||||||
|
struct cli_credentials *creds = gensec_get_credentials(gensec_security);
|
||||||
|
enum credentials_use_kerberos use_kerberos
|
||||||
|
= cli_credentials_get_kerberos_state(creds);
|
||||||
|
return gensec_use_kerberos_mechs(mem_ctx, backends, use_kerberos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security,
|
static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security,
|
||||||
uint8_t auth_type)
|
uint8_t auth_type)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
if (!gensec_security) {
|
const struct gensec_security_ops *backend;
|
||||||
backends = gensec_security_all();
|
TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
|
||||||
} else {
|
if (!mem_ctx) {
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
return NULL;
|
||||||
}
|
}
|
||||||
|
backends = gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
for (i=0; backends && backends[i]; i++) {
|
for (i=0; backends && backends[i]; i++) {
|
||||||
if (backends[i]->auth_type == auth_type) {
|
if (backends[i]->auth_type == auth_type) {
|
||||||
return backends[i];
|
backend = backends[i];
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -58,22 +139,26 @@ const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security
|
|||||||
const char *oid_string)
|
const char *oid_string)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
if (!gensec_security) {
|
const struct gensec_security_ops *backend;
|
||||||
backends = gensec_security_all();
|
TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
|
||||||
} else {
|
if (!mem_ctx) {
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
return NULL;
|
||||||
}
|
}
|
||||||
|
backends = gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
for (i=0; backends && backends[i]; i++) {
|
for (i=0; backends && backends[i]; i++) {
|
||||||
if (backends[i]->oid) {
|
if (backends[i]->oid) {
|
||||||
for (j=0; backends[i]->oid[j]; j++) {
|
for (j=0; backends[i]->oid[j]; j++) {
|
||||||
if (backends[i]->oid[j] &&
|
if (backends[i]->oid[j] &&
|
||||||
(strcmp(backends[i]->oid[j], oid_string) == 0)) {
|
(strcmp(backends[i]->oid[j], oid_string) == 0)) {
|
||||||
return backends[i];
|
backend = backends[i];
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -82,18 +167,22 @@ static const struct gensec_security_ops *gensec_security_by_sasl_name(struct gen
|
|||||||
const char *sasl_name)
|
const char *sasl_name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
if (!gensec_security) {
|
const struct gensec_security_ops *backend;
|
||||||
backends = gensec_security_all();
|
TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
|
||||||
} else {
|
if (!mem_ctx) {
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
return NULL;
|
||||||
}
|
}
|
||||||
|
backends = gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
for (i=0; backends && backends[i]; i++) {
|
for (i=0; backends && backends[i]; i++) {
|
||||||
if (backends[i]->sasl_name
|
if (backends[i]->sasl_name
|
||||||
&& (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
|
&& (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
|
||||||
return backends[i];
|
backend = backends[i];
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -102,19 +191,22 @@ static const struct gensec_security_ops *gensec_security_by_name(struct gensec_s
|
|||||||
const char *name)
|
const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
if (!gensec_security) {
|
const struct gensec_security_ops *backend;
|
||||||
backends = gensec_security_all();
|
TALLOC_CTX *mem_ctx = talloc_new(gensec_security);
|
||||||
} else {
|
if (!mem_ctx) {
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
return NULL;
|
||||||
}
|
}
|
||||||
|
backends = gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
for (i=0; backends && backends[i]; i++) {
|
for (i=0; backends && backends[i]; i++) {
|
||||||
if (backends[i]->name
|
if (backends[i]->name
|
||||||
&& (strcmp(backends[i]->name, name) == 0)) {
|
&& (strcmp(backends[i]->name, name) == 0)) {
|
||||||
return backends[i];
|
backend = backends[i];
|
||||||
|
talloc_free(mem_ctx);
|
||||||
|
return backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
talloc_free(mem_ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +223,7 @@ const struct gensec_security_ops **gensec_security_by_sasl(struct gensec_securit
|
|||||||
const char **sasl_names)
|
const char **sasl_names)
|
||||||
{
|
{
|
||||||
const struct gensec_security_ops **backends_out;
|
const struct gensec_security_ops **backends_out;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
int i, k, sasl_idx;
|
int i, k, sasl_idx;
|
||||||
int num_backends_out = 0;
|
int num_backends_out = 0;
|
||||||
|
|
||||||
@@ -139,7 +231,7 @@ const struct gensec_security_ops **gensec_security_by_sasl(struct gensec_securit
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
backends = gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
|
|
||||||
backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
|
backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
|
||||||
if (!backends_out) {
|
if (!backends_out) {
|
||||||
@@ -198,7 +290,7 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gen
|
|||||||
const char *skip)
|
const char *skip)
|
||||||
{
|
{
|
||||||
struct gensec_security_ops_wrapper *backends_out;
|
struct gensec_security_ops_wrapper *backends_out;
|
||||||
const struct gensec_security_ops **backends;
|
struct gensec_security_ops **backends;
|
||||||
int i, j, k, oid_idx;
|
int i, j, k, oid_idx;
|
||||||
int num_backends_out = 0;
|
int num_backends_out = 0;
|
||||||
|
|
||||||
@@ -206,7 +298,7 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gen
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
backends = gensec_security_mechs(gensec_security, gensec_security);
|
||||||
|
|
||||||
backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
|
backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
|
||||||
if (!backends_out) {
|
if (!backends_out) {
|
||||||
@@ -267,7 +359,7 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gen
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx,
|
const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx,
|
||||||
const struct gensec_security_ops **ops,
|
struct gensec_security_ops **ops,
|
||||||
const char *skip)
|
const char *skip)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -354,8 +446,8 @@ const char **gensec_security_oids(struct gensec_security *gensec_security,
|
|||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const char *skip)
|
const char *skip)
|
||||||
{
|
{
|
||||||
const struct gensec_security_ops **ops
|
struct gensec_security_ops **ops
|
||||||
= cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
= gensec_security_mechs(gensec_security, mem_ctx);
|
||||||
return gensec_security_oids_from_ops(mem_ctx, ops, skip);
|
return gensec_security_oids_from_ops(mem_ctx, ops, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,10 +1036,8 @@ const char *gensec_get_target_principal(struct gensec_security *gensec_security)
|
|||||||
The 'name' can be later used by other backends to find the operations
|
The 'name' can be later used by other backends to find the operations
|
||||||
structure for this backend.
|
structure for this backend.
|
||||||
*/
|
*/
|
||||||
NTSTATUS gensec_register(const void *_ops)
|
NTSTATUS gensec_register(const struct gensec_security_ops *ops)
|
||||||
{
|
{
|
||||||
const struct gensec_security_ops *ops = _ops;
|
|
||||||
|
|
||||||
if (!lp_parm_bool(-1, "gensec", ops->name, ops->enabled)) {
|
if (!lp_parm_bool(-1, "gensec", ops->name, ops->enabled)) {
|
||||||
DEBUG(2,("gensec subsystem %s is disabled\n", ops->name));
|
DEBUG(2,("gensec subsystem %s is disabled\n", ops->name));
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@@ -960,11 +1050,12 @@ NTSTATUS gensec_register(const void *_ops)
|
|||||||
return NT_STATUS_OBJECT_NAME_COLLISION;
|
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_security_ops = realloc_p(generic_security_ops,
|
generic_security_ops = talloc_realloc(talloc_autofree_context(),
|
||||||
const struct gensec_security_ops *,
|
generic_security_ops,
|
||||||
gensec_num_backends+2);
|
struct gensec_security_ops *,
|
||||||
|
gensec_num_backends+2);
|
||||||
if (!generic_security_ops) {
|
if (!generic_security_ops) {
|
||||||
smb_panic("out of memory in gensec_register");
|
smb_panic("out of memory (or failed to realloc referenced memory) in gensec_register");
|
||||||
}
|
}
|
||||||
|
|
||||||
generic_security_ops[gensec_num_backends] = ops;
|
generic_security_ops[gensec_num_backends] = ops;
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ struct gensec_security_ops {
|
|||||||
BOOL (*have_feature)(struct gensec_security *gensec_security,
|
BOOL (*have_feature)(struct gensec_security *gensec_security,
|
||||||
uint32_t feature);
|
uint32_t feature);
|
||||||
BOOL enabled;
|
BOOL enabled;
|
||||||
|
BOOL kerberos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gensec_security_ops_wrapper {
|
struct gensec_security_ops_wrapper {
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi
|
|||||||
|
|
||||||
if (!machine_account) {
|
if (!machine_account) {
|
||||||
DEBUG(3, ("No machine account credentials specified\n"));
|
DEBUG(3, ("No machine account credentials specified\n"));
|
||||||
return NT_STATUS_INVALID_PARAMETER;
|
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||||
} else {
|
} else {
|
||||||
ret = cli_credentials_get_server_gss_creds(machine_account, &gcc);
|
ret = cli_credentials_get_server_gss_creds(machine_account, &gcc);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -933,7 +933,8 @@ static const struct gensec_security_ops gensec_gssapi_krb5_security_ops = {
|
|||||||
.wrap = gensec_gssapi_wrap,
|
.wrap = gensec_gssapi_wrap,
|
||||||
.unwrap = gensec_gssapi_unwrap,
|
.unwrap = gensec_gssapi_unwrap,
|
||||||
.have_feature = gensec_gssapi_have_feature,
|
.have_feature = gensec_gssapi_have_feature,
|
||||||
.enabled = True
|
.enabled = True,
|
||||||
|
.kerberos = True
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS gensec_gssapi_init(void)
|
NTSTATUS gensec_gssapi_init(void)
|
||||||
|
|||||||
@@ -718,7 +718,8 @@ static const struct gensec_security_ops gensec_fake_gssapi_krb5_security_ops = {
|
|||||||
.session_key = gensec_krb5_session_key,
|
.session_key = gensec_krb5_session_key,
|
||||||
.session_info = gensec_krb5_session_info,
|
.session_info = gensec_krb5_session_info,
|
||||||
.have_feature = gensec_krb5_have_feature,
|
.have_feature = gensec_krb5_have_feature,
|
||||||
.enabled = False
|
.enabled = False,
|
||||||
|
.kerberos = True
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct gensec_security_ops gensec_krb5_security_ops = {
|
static const struct gensec_security_ops gensec_krb5_security_ops = {
|
||||||
@@ -731,7 +732,8 @@ static const struct gensec_security_ops gensec_krb5_security_ops = {
|
|||||||
.have_feature = gensec_krb5_have_feature,
|
.have_feature = gensec_krb5_have_feature,
|
||||||
.wrap = gensec_krb5_wrap,
|
.wrap = gensec_krb5_wrap,
|
||||||
.unwrap = gensec_krb5_unwrap,
|
.unwrap = gensec_krb5_unwrap,
|
||||||
.enabled = True
|
.enabled = True,
|
||||||
|
.kerberos = True
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS gensec_krb5_init(void)
|
NTSTATUS gensec_krb5_init(void)
|
||||||
|
|||||||
@@ -246,8 +246,8 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec
|
|||||||
const DATA_BLOB in, DATA_BLOB *out)
|
const DATA_BLOB in, DATA_BLOB *out)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
const struct gensec_security_ops **all_ops
|
struct gensec_security_ops **all_ops
|
||||||
= cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
|
= gensec_security_mechs(gensec_security, out_mem_ctx);
|
||||||
for (i=0; all_ops[i]; i++) {
|
for (i=0; all_ops[i]; i++) {
|
||||||
BOOL is_spnego;
|
BOOL is_spnego;
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@@ -341,7 +341,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
|
|||||||
out_mem_ctx,
|
out_mem_ctx,
|
||||||
unwrapped_in,
|
unwrapped_in,
|
||||||
unwrapped_out);
|
unwrapped_out);
|
||||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) {
|
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) ||
|
||||||
|
NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
|
||||||
/* Pretend we never started it (lets the first run find some incompatible demand) */
|
/* Pretend we never started it (lets the first run find some incompatible demand) */
|
||||||
|
|
||||||
DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed to parse: %s\n",
|
DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed to parse: %s\n",
|
||||||
@@ -929,7 +930,7 @@ static const struct gensec_security_ops gensec_spnego_security_ops = {
|
|||||||
.session_key = gensec_spnego_session_key,
|
.session_key = gensec_spnego_session_key,
|
||||||
.session_info = gensec_spnego_session_info,
|
.session_info = gensec_spnego_session_info,
|
||||||
.have_feature = gensec_spnego_have_feature,
|
.have_feature = gensec_spnego_have_feature,
|
||||||
.enabled = True
|
.enabled = True,
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS gensec_spnego_init(void)
|
NTSTATUS gensec_spnego_init(void)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "lib/cmdline/popt_common.h"
|
#include "lib/cmdline/popt_common.h"
|
||||||
|
#include "auth/gensec/gensec.h"
|
||||||
|
|
||||||
/* Handle command line options:
|
/* Handle command line options:
|
||||||
* -U,--user
|
* -U,--user
|
||||||
@@ -28,13 +29,16 @@
|
|||||||
* -k,--use-kerberos
|
* -k,--use-kerberos
|
||||||
* -N,--no-pass
|
* -N,--no-pass
|
||||||
* -S,--signing
|
* -S,--signing
|
||||||
* -P --machine-pass
|
* -P --machine-pass
|
||||||
|
* --simple-bind-dn
|
||||||
|
* --password
|
||||||
|
* --use-security-mechanisms
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static BOOL dont_ask;
|
static BOOL dont_ask;
|
||||||
|
|
||||||
enum opt { OPT_SIMPLE_BIND_DN };
|
enum opt { OPT_SIMPLE_BIND_DN, OPT_PASSWORD, OPT_KERBEROS, OPT_GENSEC_MECHS };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
disable asking for a password
|
disable asking for a password
|
||||||
@@ -73,11 +77,18 @@ static void popt_common_credentials_callback(poptContext con,
|
|||||||
if ((lp=strchr_m(arg,'%'))) {
|
if ((lp=strchr_m(arg,'%'))) {
|
||||||
lp[0]='\0';
|
lp[0]='\0';
|
||||||
lp++;
|
lp++;
|
||||||
|
/* Try to prevent this showing up in ps */
|
||||||
memset(lp,0,strlen(lp));
|
memset(lp,0,strlen(lp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_PASSWORD:
|
||||||
|
cli_credentials_set_password(cmdline_credentials, arg, CRED_SPECIFIED);
|
||||||
|
/* Try to prevent this showing up in ps */
|
||||||
|
memset(arg,0,strlen(arg));
|
||||||
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
cli_credentials_parse_file(cmdline_credentials, arg, CRED_SPECIFIED);
|
cli_credentials_parse_file(cmdline_credentials, arg, CRED_SPECIFIED);
|
||||||
break;
|
break;
|
||||||
@@ -89,9 +100,31 @@ static void popt_common_credentials_callback(poptContext con,
|
|||||||
case 'P':
|
case 'P':
|
||||||
/* Later, after this is all over, get the machine account details from the secrets.ldb */
|
/* Later, after this is all over, get the machine account details from the secrets.ldb */
|
||||||
cli_credentials_set_machine_account_pending(cmdline_credentials);
|
cli_credentials_set_machine_account_pending(cmdline_credentials);
|
||||||
|
|
||||||
/* machine accounts only work with kerberos (fall though)*/
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OPT_KERBEROS:
|
||||||
|
{
|
||||||
|
BOOL use_kerberos = True;
|
||||||
|
/* Force us to only use kerberos */
|
||||||
|
if (arg) {
|
||||||
|
if (!set_boolean(arg, &use_kerberos)) {
|
||||||
|
fprintf(stderr, "Error parsing -k %s\n", arg);
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cli_credentials_set_kerberos_state(cmdline_credentials,
|
||||||
|
use_kerberos
|
||||||
|
? CRED_MUST_USE_KERBEROS
|
||||||
|
: CRED_DONT_USE_KERBEROS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OPT_GENSEC_MECHS:
|
||||||
|
/* Convert a list of strings into a list of available authentication standards */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case OPT_SIMPLE_BIND_DN:
|
case OPT_SIMPLE_BIND_DN:
|
||||||
cli_credentials_set_bind_dn(cmdline_credentials, arg);
|
cli_credentials_set_bind_dn(cmdline_credentials, arg);
|
||||||
break;
|
break;
|
||||||
@@ -104,9 +137,12 @@ struct poptOption popt_common_credentials[] = {
|
|||||||
{ NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, popt_common_credentials_callback },
|
{ NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, popt_common_credentials_callback },
|
||||||
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN\\]USERNAME[%PASSWORD]" },
|
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "[DOMAIN\\]USERNAME[%PASSWORD]" },
|
||||||
{ "no-pass", 'N', POPT_ARG_NONE, &dont_ask, True, "Don't ask for a password" },
|
{ "no-pass", 'N', POPT_ARG_NONE, &dont_ask, True, "Don't ask for a password" },
|
||||||
|
{ "password", 0, POPT_ARG_STRING, NULL, OPT_PASSWORD, "Password" },
|
||||||
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
|
{ "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
|
||||||
{ "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
|
{ "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
|
||||||
{ "machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password (implies -k)" },
|
{ "machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password (implies -k)" },
|
||||||
{ "simple-bind-dn", 0, POPT_ARG_STRING, NULL, OPT_SIMPLE_BIND_DN, "DN to use for a simple bind" },
|
{ "simple-bind-dn", 0, POPT_ARG_STRING, NULL, OPT_SIMPLE_BIND_DN, "DN to use for a simple bind" },
|
||||||
|
{ "kerberos", 'k', POPT_ARG_STRING, NULL, OPT_KERBEROS, "Use Kerberos" },
|
||||||
|
{ "use-security-mechanisms", 0, POPT_ARG_STRING, NULL, OPT_GENSEC_MECHS, "Restricted list of authentication mechanisms available for use with this authentication"},
|
||||||
POPT_TABLEEND
|
POPT_TABLEEND
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1111,3 +1111,28 @@ char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
Set a boolean variable from the text value stored in the passed string.
|
||||||
|
Returns True in success, False if the passed string does not correctly
|
||||||
|
represent a boolean.
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
BOOL set_boolean(const char *boolean_string, BOOL *boolean)
|
||||||
|
{
|
||||||
|
if (strwicmp(boolean_string, "yes") == 0 ||
|
||||||
|
strwicmp(boolean_string, "true") == 0 ||
|
||||||
|
strwicmp(boolean_string, "on") == 0 ||
|
||||||
|
strwicmp(boolean_string, "1") == 0) {
|
||||||
|
*boolean = True;
|
||||||
|
return True;
|
||||||
|
} else if (strwicmp(boolean_string, "no") == 0 ||
|
||||||
|
strwicmp(boolean_string, "false") == 0 ||
|
||||||
|
strwicmp(boolean_string, "off") == 0 ||
|
||||||
|
strwicmp(boolean_string, "0") == 0) {
|
||||||
|
*boolean = False;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -912,7 +912,6 @@ FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
|
|||||||
/* local prototypes */
|
/* local prototypes */
|
||||||
|
|
||||||
static int map_parameter(const char *pszParmName);
|
static int map_parameter(const char *pszParmName);
|
||||||
static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
|
|
||||||
static int getservicebyname(const char *pszServiceName,
|
static int getservicebyname(const char *pszServiceName,
|
||||||
service * pserviceDest);
|
service * pserviceDest);
|
||||||
static void copy_service(service * pserviceDest,
|
static void copy_service(service * pserviceDest,
|
||||||
@@ -1004,7 +1003,7 @@ static BOOL lp_bool(const char *s)
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_boolean(&ret,s)) {
|
if (!set_boolean(s, &ret)) {
|
||||||
DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
|
DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
@@ -1373,34 +1372,6 @@ void *lp_parm_ptr(int snum, struct parm_struct *parm)
|
|||||||
return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
|
return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Set a boolean variable from the text value stored in the passed string.
|
|
||||||
Returns True in success, False if the passed string does not correctly
|
|
||||||
represent a boolean.
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
|
|
||||||
{
|
|
||||||
BOOL bRetval;
|
|
||||||
|
|
||||||
bRetval = True;
|
|
||||||
if (strwicmp(pszParmValue, "yes") == 0 ||
|
|
||||||
strwicmp(pszParmValue, "true") == 0 ||
|
|
||||||
strwicmp(pszParmValue, "1") == 0)
|
|
||||||
*pb = True;
|
|
||||||
else if (strwicmp(pszParmValue, "no") == 0 ||
|
|
||||||
strwicmp(pszParmValue, "False") == 0 ||
|
|
||||||
strwicmp(pszParmValue, "0") == 0)
|
|
||||||
*pb = False;
|
|
||||||
else {
|
|
||||||
DEBUG(0,
|
|
||||||
("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
|
|
||||||
pszParmValue));
|
|
||||||
bRetval = False;
|
|
||||||
}
|
|
||||||
return (bRetval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
Find a service by name. Otherwise works like get_service.
|
Find a service by name. Otherwise works like get_service.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
@@ -1841,7 +1812,10 @@ BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
|
|||||||
switch (parm_table[parmnum].type)
|
switch (parm_table[parmnum].type)
|
||||||
{
|
{
|
||||||
case P_BOOL:
|
case P_BOOL:
|
||||||
set_boolean(parm_ptr, pszParmValue);
|
if (!set_boolean(pszParmValue, parm_ptr)) {
|
||||||
|
DEBUG(0,("lp_do_parameter(%s): value is not boolean!\n", pszParmValue));
|
||||||
|
return False;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_INTEGER:
|
case P_INTEGER:
|
||||||
|
|||||||
Reference in New Issue
Block a user