1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-04 05:18:06 +03:00

r12060: Work towards allowing the credentials system to allow/deny certain

GENSEC mechansims.  This will allow a machine join to an NT4 domain to
avoid even trying kerberos, or a sensitive operation to require it.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2005-12-05 03:20:40 +00:00 committed by Gerald (Jerry) Carter
parent 6c43de2708
commit 11c7a89e52
5 changed files with 105 additions and 65 deletions

View File

@ -4,9 +4,10 @@
INIT_OBJ_FILES = credentials.o
ADD_OBJ_FILES = credentials_files.o \
credentials_krb5.o \
credentials_ntlm.o
credentials_ntlm.o \
credentials_gensec.o
REQUIRED_SUBSYSTEMS = \
HEIMDAL
# End SUBSYSTEM GENSEC
HEIMDAL GENSEC
# End SUBSYSTEM CREDENTIALS
#################################

View File

@ -55,6 +55,7 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
cred->smb_krb5_context = NULL;
cred->salt_principal = NULL;
cred->machine_account = False;
cred->gensec_list = NULL;
return cred;
}

View File

@ -91,4 +91,7 @@ struct cli_credentials {
/* Is this a machine account? */
BOOL machine_account;
/* A list of valid GENSEC mechanisms for use on this account */
struct gensec_security_ops **gensec_list;
};

View File

@ -29,27 +29,46 @@
const static struct gensec_security_ops **generic_security_ops;
static int gensec_num_backends;
static const struct gensec_security_ops *gensec_security_by_authtype(uint8_t auth_type)
const struct gensec_security_ops **gensec_security_all(void)
{
return generic_security_ops;
}
static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security,
uint8_t auth_type)
{
int i;
for (i=0; i < gensec_num_backends; i++) {
if (generic_security_ops[i]->auth_type == auth_type) {
return generic_security_ops[i];
const struct gensec_security_ops **backends;
if (!gensec_security) {
backends = gensec_security_all();
} else {
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
}
for (i=0; backends && backends[i]; i++) {
if (backends[i]->auth_type == auth_type) {
return backends[i];
}
}
return NULL;
}
static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_string)
static const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security *gensec_security,
const char *oid_string)
{
int i, j;
for (i=0; i < gensec_num_backends; 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];
const struct gensec_security_ops **backends;
if (!gensec_security) {
backends = gensec_security_all();
} else {
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
}
for (i=0; backends && backends[i]; i++) {
if (backends[i]->oid) {
for (j=0; backends[i]->oid[j]; j++) {
if (backends[i]->oid[j] &&
(strcmp(backends[i]->oid[j], oid_string) == 0)) {
return backends[i];
}
}
}
@ -58,60 +77,68 @@ static const struct gensec_security_ops *gensec_security_by_oid(const char *oid_
return NULL;
}
static const struct gensec_security_ops *gensec_security_by_sasl_name(const char *sasl_name)
static const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_security *gensec_security,
const char *sasl_name)
{
int i;
for (i=0; i < gensec_num_backends; i++) {
if (generic_security_ops[i]->sasl_name
&& (strcmp(generic_security_ops[i]->sasl_name, sasl_name) == 0)) {
return generic_security_ops[i];
const struct gensec_security_ops **backends;
if (!gensec_security) {
backends = gensec_security_all();
} else {
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
}
for (i=0; backends && backends[i]; i++) {
if (backends[i]->sasl_name
&& (strcmp(backends[i]->sasl_name, sasl_name) == 0)) {
return backends[i];
}
}
return NULL;
}
static const struct gensec_security_ops *gensec_security_by_name(const char *name)
static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security,
const char *name)
{
int i;
for (i=0; i < gensec_num_backends; i++) {
if (generic_security_ops[i]->name
&& (strcmp(generic_security_ops[i]->name, name) == 0)) {
return generic_security_ops[i];
const struct gensec_security_ops **backends;
if (!gensec_security) {
backends = gensec_security_all();
} else {
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
}
for (i=0; backends && backends[i]; i++) {
if (backends[i]->name
&& (strcmp(backends[i]->name, name) == 0)) {
return backends[i];
}
}
return NULL;
}
const struct gensec_security_ops **gensec_security_all(int *num_backends_out)
{
*num_backends_out = gensec_num_backends;
return generic_security_ops;
}
/**
* 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 of SASL names.
*
* The list is in the exact order of the OIDs asked for, where available.
* Use the list of enabled GENSEC mechanisms from the credentials
* attached to the gensec_security, and return in our preferred order.
*/
const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
const char **sasl_names)
const struct gensec_security_ops **gensec_security_by_sasl(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
const char **sasl_names)
{
const struct gensec_security_ops **backends_out;
const struct gensec_security_ops **backends;
int i, k, sasl_idx;
int num_backends_out = 0;
int num_backends;
if (!sasl_names) {
return NULL;
}
backends = gensec_security_all(&num_backends);
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1);
if (!backends_out) {
@ -121,7 +148,7 @@ const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
/* Find backends in our preferred order, by walking our list,
* then looking in the supplied list */
for (i=0; i < num_backends; i++) {
for (i=0; backends && backends[i]; i++) {
for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) {
if (!backends[i]->sasl_name ||
!(strcmp(backends[i]->sasl_name,
@ -158,12 +185,14 @@ const struct gensec_security_ops **gensec_security_by_sasl(TALLOC_CTX *mem_ctx,
/**
* 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
* return that module only once.
*
* The list is in the exact order of the OIDs asked for, where available.
* Use the list of enabled GENSEC mechanisms from the credentials
* attached to the gensec_security, and return in our preferred order.
*/
const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX *mem_ctx,
const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gensec_security *gensec_security,
TALLOC_CTX *mem_ctx,
const char **oid_strings,
const char *skip)
{
@ -171,13 +200,12 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
const struct gensec_security_ops **backends;
int i, j, k, oid_idx;
int num_backends_out = 0;
int num_backends;
if (!oid_strings) {
return NULL;
}
backends = gensec_security_all(&num_backends);
backends = cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1);
if (!backends_out) {
@ -188,7 +216,7 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
/* Find backends in our preferred order, by walking our list,
* then looking in the supplied list */
for (i=0; i < num_backends; i++) {
for (i=0; backends && backends[i]; i++) {
if (!backends[i]->oid) {
continue;
}
@ -239,7 +267,6 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(TALLOC_CTX
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;
@ -254,7 +281,7 @@ const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx,
return NULL;
}
for (i=0; i<num_backends; i++) {
for (i=0; ops && ops[i]; i++) {
if (!ops[i]->oid) {
continue;
}
@ -315,15 +342,20 @@ const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX *mem_ctx,
/**
* Return all the security subsystems currently enabled in GENSEC
* Return all the security subsystems currently enabled on a GENSEC context.
*
* This is taken from a list attached to the cli_credentails, and
* skips the OID in 'skip'. (Typically the SPNEGO OID)
*
*/
const char **gensec_security_oids(TALLOC_CTX *mem_ctx, const char *skip)
const char **gensec_security_oids(struct gensec_security *gensec_security,
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);
const struct gensec_security_ops **ops
= cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
return gensec_security_oids_from_ops(mem_ctx, ops, skip);
}
@ -465,7 +497,7 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security)
NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
uint8_t auth_type, uint8_t auth_level)
{
gensec_security->ops = gensec_security_by_authtype(auth_type);
gensec_security->ops = gensec_security_by_authtype(gensec_security, auth_type);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
return NT_STATUS_INVALID_PARAMETER;
@ -491,7 +523,7 @@ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
const char *gensec_get_name_by_authtype(uint8_t authtype)
{
const struct gensec_security_ops *ops;
ops = gensec_security_by_authtype(authtype);
ops = gensec_security_by_authtype(NULL, authtype);
if (ops) {
return ops->name;
}
@ -502,7 +534,7 @@ const char *gensec_get_name_by_authtype(uint8_t authtype)
const char *gensec_get_name_by_oid(const char *oid_string)
{
const struct gensec_security_ops *ops;
ops = gensec_security_by_oid(oid_string);
ops = gensec_security_by_oid(NULL, oid_string);
if (ops) {
return ops->name;
}
@ -532,7 +564,7 @@ NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
const char *mech_oid)
{
gensec_security->ops = gensec_security_by_oid(mech_oid);
gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid));
return NT_STATUS_INVALID_PARAMETER;
@ -548,7 +580,7 @@ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
const char *sasl_name)
{
gensec_security->ops = gensec_security_by_sasl_name(sasl_name);
gensec_security->ops = gensec_security_by_sasl_name(gensec_security, sasl_name);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name));
return NT_STATUS_INVALID_PARAMETER;
@ -564,7 +596,7 @@ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
const char *name)
{
gensec_security->ops = gensec_security_by_name(name);
gensec_security->ops = gensec_security_by_name(gensec_security, name);
if (!gensec_security->ops) {
DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name));
return NT_STATUS_INVALID_PARAMETER;
@ -862,7 +894,7 @@ NTSTATUS gensec_register(const void *_ops)
return NT_STATUS_OK;
}
if (gensec_security_by_name(ops->name) != NULL) {
if (gensec_security_by_name(NULL, ops->name) != NULL) {
/* its already registered! */
DEBUG(0,("GENSEC backend '%s' already registered\n",
ops->name));

View File

@ -247,9 +247,9 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec
const DATA_BLOB in, DATA_BLOB *out)
{
int i,j;
int num_ops;
const struct gensec_security_ops **all_ops = gensec_security_all(&num_ops);
for (i=0; i < num_ops; i++) {
const struct gensec_security_ops **all_ops
= cli_credentials_gensec_list(gensec_get_credentials(gensec_security));
for (i=0; all_ops[i]; i++) {
BOOL is_spnego;
NTSTATUS nt_status;
if (!all_ops[i]->oid) {
@ -315,7 +315,8 @@ static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_
DATA_BLOB null_data_blob = data_blob(NULL,0);
const struct gensec_security_ops_wrapper *all_sec
= gensec_security_by_oid_list(out_mem_ctx,
= gensec_security_by_oid_list(gensec_security,
out_mem_ctx,
mechType,
GENSEC_OID_SPNEGO);
for (i=0; all_sec && all_sec[i].op; i++) {
@ -413,9 +414,11 @@ static NTSTATUS gensec_spnego_create_negTokenInit(struct gensec_security *gensec
const struct gensec_security_ops_wrapper *all_sec;
const char *principal = NULL;
mechTypes = gensec_security_oids(out_mem_ctx, GENSEC_OID_SPNEGO);
mechTypes = gensec_security_oids(gensec_security,
out_mem_ctx, GENSEC_OID_SPNEGO);
all_sec = gensec_security_by_oid_list(out_mem_ctx,
all_sec = gensec_security_by_oid_list(gensec_security,
out_mem_ctx,
mechTypes,
GENSEC_OID_SPNEGO);
for (i=0; all_sec && all_sec[i].op; i++) {