1
0
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:
Andrew Bartlett
2006-01-28 12:15:24 +00:00
committed by Gerald (Jerry) Carter
parent 78d634047f
commit 1ac7976ea6
13 changed files with 245 additions and 171 deletions

View File

@@ -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
################################# #################################

View File

@@ -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

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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];

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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
}; };

View File

@@ -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;
}

View File

@@ -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: