r11270: Move the core CrackNames code from rpc_server/drsuapi to dsdb/samdb.
authorAndrew Bartlett <abartlet@samba.org>
Sun, 23 Oct 2005 22:20:42 +0000 (22:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:45:11 +0000 (13:45 -0500)
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

source/auth/auth_sam.c
source/auth/gensec/gensec_gssapi.c
source/auth/gensec/gensec_krb5.c
source/dsdb/config.mk
source/dsdb/samdb/cracknames.c [moved from source/rpc_server/drsuapi/drsuapi_cracknames.c with 92% similarity]
source/include/structs.h
source/kdc/pac-glue.c
source/rpc_server/config.mk
source/rpc_server/drsuapi/dcesrv_drsuapi.c

index de4be9586ca9c02dac2b413991d2ce3fc2d9d818..9fd011ea303ce8c3d287d899a040242cda12c248 100644 (file)
 #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;
 }
 
index 42141e4df24ffb0b5db537b54f5a200218d74691..8fcada2352781c913d92b348c2d73934fc3237a5 100644 (file)
@@ -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);
index 64de8211dd2b60be3fbfeb2018069b38d3369ec8..3ed38a435c63e88fb55b087c7a4e5fe6799f6e21 100644 (file)
@@ -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);
index 59178c3cda52f1f7c3892ca2a9beef6a3d878b08..065eb65afa9afd3680de16c5938405ac9db52a0f 100644 (file)
@@ -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
similarity index 92%
rename from source/rpc_server/drsuapi/drsuapi_cracknames.c
rename to source/dsdb/samdb/cracknames.c
index 3a4d33715423d1fa556643d2934345565702dec7..6b04d05ad8e0893ba3dce2a4537327ed00d397e2 100644 (file)
@@ -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:
index 483c601583993d28f7599f37d641fea0931000d9..950d0baaa21da7fd1b9fcf8de1f2b500ca55539d 100644 (file)
@@ -78,6 +78,7 @@ struct ntptr_context;
 struct ntptr_GenericHandle;
 
 struct drsuapi_DsCrackNames;
+struct drsuapi_DsNameInfo1;
 struct drsuapi_DsReplicaObjectListItem;
 struct drsuapi_DsReplicaObjectListItemEx;
 
index 20578a786e52c07272936f3718ee0b599bfd76aa..47cd31583e1a349e882033fa2cfac9a669cf2edc 100644 (file)
        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");
                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)));
index 1d6913c40b363ac1155965d6b334365a53526a6f..821c60978a0da525b558d9c3131c23a1011a9b37 100644 (file)
@@ -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 \
index c8578a7cc119a40ffc7c25ce95719cef72fbfb08..a762b448787064365ebc9ac3584078817d01c944 100644 (file)
@@ -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