summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-10-23 22:20:42 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:45:11 -0500
commitdb4b95827e4e6d13577513946bff4f956c849756 (patch)
treed87779f6511101d981bf958a90bdaddca92f8744
parent28a3bc645b49ea6e997b3576ba7a8ba55e7caa9c (diff)
downloadsamba-db4b95827e4e6d13577513946bff4f956c849756.tar.gz
samba-db4b95827e4e6d13577513946bff4f956c849756.tar.bz2
samba-db4b95827e4e6d13577513946bff4f956c849756.zip
r11270: Move the core CrackNames code from rpc_server/drsuapi to dsdb/samdb.
I'm sure this will not be the final resting place, but it will do for now. Use the cracknames code in auth/ for creating a server_info given a principal name only (should avoid assumtions about spliting a user@realm principal). Andrew Bartlett (This used to be commit c9d5d8e45dd7b7c99b6cf35b087bc18012f31222)
-rw-r--r--source4/auth/auth_sam.c109
-rw-r--r--source4/auth/gensec/gensec_gssapi.c41
-rw-r--r--source4/auth/gensec/gensec_krb5.c19
-rw-r--r--source4/dsdb/config.mk1
-rw-r--r--source4/dsdb/samdb/cracknames.c (renamed from source4/rpc_server/drsuapi/drsuapi_cracknames.c)68
-rw-r--r--source4/include/structs.h1
-rw-r--r--source4/kdc/pac-glue.c14
-rw-r--r--source4/rpc_server/config.mk2
-rw-r--r--source4/rpc_server/drsuapi/dcesrv_drsuapi.c53
9 files changed, 143 insertions, 165 deletions
diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c
index de4be9586c..9fd011ea30 100644
--- a/source4/auth/auth_sam.c
+++ b/source4/auth/auth_sam.c
@@ -26,6 +26,31 @@
#include "auth/auth.h"
#include "lib/ldb/include/ldb.h"
+const char *user_attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash",
+ "userAccountControl",
+ "pwdLastSet",
+ "accountExpires",
+ "objectSid",
+ "userWorkstations",
+
+ /* required for server_info, not access control: */
+ "sAMAccountName",
+ "displayName",
+ "scriptPath",
+ "profilePath",
+ "homeDirectory",
+ "homeDrive",
+ "lastLogon",
+ "lastLogoff",
+ "accountExpires",
+ "badPwdCount",
+ "logonCount",
+ "primaryGroupID",
+ NULL,
+};
+
+const char *domain_attrs[] = {"nETBIOSName", "nCName", NULL};
+
/****************************************************************************
Do a specific test for an smb password being correct, given a smb_password and
the lanman and NT responses.
@@ -217,31 +242,6 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
const struct ldb_dn *domain_dn = NULL;
- const char *attrs[] = {"unicodePwd", "lmPwdHash", "ntPwdHash",
- "userAccountControl",
- "pwdLastSet",
- "accountExpires",
- "objectSid",
- "userWorkstations",
-
- /* required for server_info, not access control: */
- "sAMAccountName",
- "displayName",
- "scriptPath",
- "profilePath",
- "homeDirectory",
- "homeDrive",
- "lastLogon",
- "lastLogoff",
- "accountExpires",
- "badPwdCount",
- "logonCount",
- "primaryGroupID",
- NULL,
- };
-
- const char *domain_attrs[] = {"nETBIOSName", "nCName", NULL};
-
if (domain_name) {
/* find the domain's DN */
ret_domain = gendb_search(sam_ctx, mem_ctx, NULL, &msgs_domain, domain_attrs,
@@ -267,7 +267,7 @@ static NTSTATUS authsam_search_account(TALLOC_CTX *mem_ctx, struct ldb_context *
}
/* pull the user attributes */
- ret = gendb_search(sam_ctx, mem_ctx, domain_dn, &msgs, attrs,
+ ret = gendb_search(sam_ctx, mem_ctx, domain_dn, &msgs, user_attrs,
"(&(sAMAccountName=%s)(objectclass=user))",
account_name);
if (ret == -1) {
@@ -511,32 +511,61 @@ static NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context
return NT_STATUS_OK;
}
-NTSTATUS sam_get_server_info(TALLOC_CTX *mem_ctx, const char *account_name, const char *domain_name,
- DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
- struct auth_serversupplied_info **server_info)
+NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, const char *principal,
+ struct auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
+ DATA_BLOB user_sess_key = data_blob(NULL, 0);
+ DATA_BLOB lm_sess_key = data_blob(NULL, 0);
+ struct ldb_dn *user_dn, *domain_dn;
struct ldb_message **msgs;
- struct ldb_message **domain_msgs;
- void *sam_ctx;
+ struct ldb_message **msgs_domain;
+ struct ldb_context *sam_ctx;
- sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx));
+ int ret_domain, ret;
+
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ sam_ctx = samdb_connect(tmp_ctx, system_session(tmp_ctx));
if (sam_ctx == NULL) {
+ talloc_free(tmp_ctx);
return NT_STATUS_INVALID_SYSTEM_SERVICE;
}
- nt_status = authsam_search_account(mem_ctx, sam_ctx, account_name, domain_name, &msgs, &domain_msgs);
- NT_STATUS_NOT_OK_RETURN(nt_status);
+ nt_status = crack_user_principal_name(sam_ctx, tmp_ctx, principal, &user_dn, &domain_dn);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(tmp_ctx);
+ return nt_status;
+ }
+
+ /* grab domain info */
+ ret_domain = gendb_search_dn(sam_ctx, tmp_ctx,
+ domain_dn, &msgs_domain, domain_attrs);
- nt_status = authsam_make_server_info(mem_ctx, sam_ctx, msgs, domain_msgs,
+ if (ret_domain != 1) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ /* pull the user attributes */
+ ret = gendb_search_dn(sam_ctx, tmp_ctx,
+ user_dn, &msgs, user_attrs);
+ if (ret != 1) {
+ talloc_free(tmp_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ nt_status = authsam_make_server_info(mem_ctx, sam_ctx, msgs, msgs_domain,
user_sess_key, lm_sess_key,
server_info);
- NT_STATUS_NOT_OK_RETURN(nt_status);
-
- talloc_free(msgs);
- talloc_free(domain_msgs);
-
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(tmp_ctx);
+ return nt_status;
+ }
return NT_STATUS_OK;
}
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 42141e4df2..8fcada2352 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -879,6 +879,10 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
}
}
+ /* IF we have the PAC - otherwise we need to get this
+ * data from elsewere - local ldb, or (TODO) lookup of some
+ * kind...
+ */
if (maj_stat == 0) {
krb5_error_code ret;
@@ -912,42 +916,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
}
if (maj_stat) {
- krb5_error_code ret;
- DATA_BLOB user_sess_key = data_blob(NULL, 0);
- DATA_BLOB lm_sess_key = data_blob(NULL, 0);
- /* IF we have the PAC - otherwise we need to get this
- * data from elsewere - local ldb, or (TODO) lookup of some
- * kind...
- *
- * when heimdal can generate the PAC, we should fail if there's
- * no PAC present
- */
-
- char *account_name;
- const char *realm;
- ret = krb5_parse_name(gensec_gssapi_state->smb_krb5_context->krb5_context,
- principal_string, &principal);
- if (ret) {
- talloc_free(mem_ctx);
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- realm = krb5_principal_get_realm(gensec_gssapi_state->smb_krb5_context->krb5_context,
- principal);
- ret = krb5_unparse_name_norealm(gensec_gssapi_state->smb_krb5_context->krb5_context,
- principal, &account_name);
- if (ret) {
- krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal);
- talloc_free(mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
DEBUG(1, ("Unable to use PAC, resorting to local user lookup!\n"));
- nt_status = sam_get_server_info(mem_ctx, account_name, realm,
- user_sess_key, lm_sess_key,
- &server_info);
- free(account_name);
- krb5_free_principal(gensec_gssapi_state->smb_krb5_context->krb5_context, principal);
+ nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
+ &server_info);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 64de8211dd..3ed38a435c 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -518,23 +518,16 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
if (!NT_STATUS_IS_OK(nt_status)) {
/* NO pac, or can't parse or verify it */
krb5_error_code ret;
- DATA_BLOB user_sess_key = data_blob(NULL, 0);
- DATA_BLOB lm_sess_key = data_blob(NULL, 0);
-
- char *account_name;
- const char *realm = krb5_principal_get_realm(gensec_krb5_state->smb_krb5_context->krb5_context,
- get_principal_from_tkt(gensec_krb5_state->ticket));
- ret = krb5_unparse_name_norealm(gensec_krb5_state->smb_krb5_context->krb5_context,
- get_principal_from_tkt(gensec_krb5_state->ticket), &account_name);
+ char *principal_string;
+ ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context,
+ get_principal_from_tkt(gensec_krb5_state->ticket), &principal_string);
if (ret) {
return NT_STATUS_NO_MEMORY;
}
- /* TODO: should we pass the krb5 session key in here? */
- nt_status = sam_get_server_info(mem_ctx, account_name, realm,
- user_sess_key, lm_sess_key,
- &server_info);
- free(account_name);
+ nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
+ &server_info);
+ free(principal_string);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk
index 59178c3cda..065eb65afa 100644
--- a/source4/dsdb/config.mk
+++ b/source4/dsdb/config.mk
@@ -48,6 +48,7 @@ INIT_OBJ_FILES = \
samdb/samdb.o
ADD_OBJ_FILES = \
samdb/samdb_privilege.o \
+ samdb/cracknames.o \
common/flag_mapping.o
REQUIRED_SUBSYSTEMS = \
DCERPC_COMMON
diff --git a/source4/rpc_server/drsuapi/drsuapi_cracknames.c b/source4/dsdb/samdb/cracknames.c
index 3a4d337154..6b04d05ad8 100644
--- a/source4/rpc_server/drsuapi/drsuapi_cracknames.c
+++ b/source4/dsdb/samdb/cracknames.c
@@ -37,10 +37,6 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
const struct ldb_dn *name_dn, const char *name,
const char *domain_filter, const char *result_filter,
struct drsuapi_DsNameInfo1 *info1);
-static WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
- uint32_t format_flags, uint32_t format_offered, uint32_t format_desired,
- const char *name, struct drsuapi_DsNameInfo1 *info1);
-
static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx,
uint32_t format_offered, uint32_t format_desired,
const struct ldb_dn *name_dn, const char *name,
@@ -242,9 +238,9 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
return status;
}
-static WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
- uint32_t format_flags, uint32_t format_offered, uint32_t format_desired,
- const char *name, struct drsuapi_DsNameInfo1 *info1)
+WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
+ uint32_t format_flags, uint32_t format_offered, uint32_t format_desired,
+ const char *name, struct drsuapi_DsNameInfo1 *info1)
{
krb5_error_code ret;
const char *domain_filter = NULL;
@@ -716,59 +712,6 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_
return WERR_INVALID_PARAM;
}
-/*
- drsuapi_DsCrackNames
-*/
-WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct drsuapi_DsCrackNames *r)
-{
- WERROR status;
- struct drsuapi_bind_state *b_state;
- struct dcesrv_handle *h;
-
- r->out.level = r->in.level;
- ZERO_STRUCT(r->out.ctr);
-
- DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
- b_state = h->data;
-
- switch (r->in.level) {
- case 1: {
- struct drsuapi_DsNameCtr1 *ctr1;
- struct drsuapi_DsNameInfo1 *names;
- int count;
- int i;
-
- ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1);
- WERR_TALLOC_CHECK(ctr1);
-
- count = r->in.req.req1.count;
- names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count);
- WERR_TALLOC_CHECK(names);
-
- for (i=0; i < count; i++) {
- status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx,
- r->in.req.req1.format_flags,
- r->in.req.req1.format_offered,
- r->in.req.req1.format_desired,
- r->in.req.req1.names[i].str,
- &names[i]);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
- }
-
- ctr1->count = count;
- ctr1->array = names;
- r->out.ctr.ctr1 = ctr1;
-
- return WERR_OK;
- }
- }
-
- return WERR_UNKNOWN_LEVEL;
-}
-
NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
TALLOC_CTX *mem_ctx,
const char *user_principal_name,
@@ -776,7 +719,6 @@ NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
struct ldb_dn **domain_dn)
{
WERROR werr;
- NTSTATUS status;
struct drsuapi_DsNameInfo1 info1;
werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0,
DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
@@ -784,7 +726,7 @@ NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
user_principal_name,
&info1);
if (!W_ERROR_IS_OK(werr)) {
- return NT_STATUS_NO_MEMORY;
+ return werror_to_ntstatus(werr);
}
switch (info1.status) {
case DRSUAPI_DS_NAME_STATUS_OK:
@@ -808,7 +750,7 @@ NTSTATUS crack_user_principal_name(struct ldb_context *sam_ctx,
info1.dns_domain_name),
&info1);
if (!W_ERROR_IS_OK(werr)) {
- return NT_STATUS_NO_MEMORY;
+ return werror_to_ntstatus(werr);
}
switch (info1.status) {
case DRSUAPI_DS_NAME_STATUS_OK:
diff --git a/source4/include/structs.h b/source4/include/structs.h
index 483c601583..950d0baaa2 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -78,6 +78,7 @@ struct ntptr_context;
struct ntptr_GenericHandle;
struct drsuapi_DsCrackNames;
+struct drsuapi_DsNameInfo1;
struct drsuapi_DsReplicaObjectListItem;
struct drsuapi_DsReplicaObjectListItemEx;
diff --git a/source4/kdc/pac-glue.c b/source4/kdc/pac-glue.c
index 20578a786e..47cd31583e 100644
--- a/source4/kdc/pac-glue.c
+++ b/source4/kdc/pac-glue.c
@@ -36,15 +36,14 @@
krb5_error_code ret;
NTSTATUS nt_status;
struct auth_serversupplied_info *server_info;
- char *username;
- const char *realm;
DATA_BLOB tmp_blob;
+ char *principal_string;
TALLOC_CTX *mem_ctx = talloc_named(config, 0, "samba_get_pac context");
if (!mem_ctx) {
return ENOMEM;
}
- ret = krb5_unparse_name_norealm(context, client, &username);
+ ret = krb5_unparse_name(context, client, &principal_string);
if (ret != 0) {
krb5_set_error_string(context, "get pac: could not parse principal");
@@ -53,12 +52,9 @@
return ret;
}
- /* parse the principal name */
- realm = krb5_principal_get_realm(context, client);
-
- nt_status = sam_get_server_info(mem_ctx, username, realm,
- data_blob(NULL, 0), data_blob(NULL, 0),
- &server_info);
+ nt_status = sam_get_server_info_principal(mem_ctx, principal_string,
+ &server_info);
+ free(principal_string);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("Getting user info for PAC failed: %s\n",
nt_errstr(nt_status)));
diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk
index 1d6913c40b..821c60978a 100644
--- a/source4/rpc_server/config.mk
+++ b/source4/rpc_server/config.mk
@@ -176,8 +176,6 @@ INIT_FUNCTION = dcerpc_server_drsuapi_init
SUBSYSTEM = DCERPC
INIT_OBJ_FILES = \
drsuapi/dcesrv_drsuapi.o
-ADD_OBJ_FILES = \
- drsuapi/drsuapi_cracknames.o
REQUIRED_SUBSYSTEMS = \
SAMDB \
DCERPC_COMMON \
diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
index c8578a7cc1..a762b44878 100644
--- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
+++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
@@ -201,10 +201,57 @@ static WERROR DRSUAPI_GET_NT4_CHANGELOG(struct dcesrv_call_state *dce_call, TALL
/*
- drsuapi_DsCrackNames => drsuapip_cracknames.c
+ drsuapi_DsCrackNames
*/
-static WERROR (*drsuapi_DsCrackNames)(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct drsuapi_DsCrackNames *r) = dcesrv_drsuapi_DsCrackNames;
+WERROR drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct drsuapi_DsCrackNames *r)
+{
+ WERROR status;
+ struct drsuapi_bind_state *b_state;
+ struct dcesrv_handle *h;
+
+ r->out.level = r->in.level;
+ ZERO_STRUCT(r->out.ctr);
+
+ DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
+ b_state = h->data;
+
+ switch (r->in.level) {
+ case 1: {
+ struct drsuapi_DsNameCtr1 *ctr1;
+ struct drsuapi_DsNameInfo1 *names;
+ int count;
+ int i;
+
+ ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1);
+ WERR_TALLOC_CHECK(ctr1);
+
+ count = r->in.req.req1.count;
+ names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count);
+ WERR_TALLOC_CHECK(names);
+
+ for (i=0; i < count; i++) {
+ status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx,
+ r->in.req.req1.format_flags,
+ r->in.req.req1.format_offered,
+ r->in.req.req1.format_desired,
+ r->in.req.req1.names[i].str,
+ &names[i]);
+ if (!W_ERROR_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ ctr1->count = count;
+ ctr1->array = names;
+ r->out.ctr.ctr1 = ctr1;
+
+ return WERR_OK;
+ }
+ }
+
+ return WERR_UNKNOWN_LEVEL;
+}
/*
drsuapi_DsWriteAccountSpn