Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/auth
Files:
13 added
18 deleted
47 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/auth.h

    r414 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Standardised Authentication types
    44   Copyright (C) Andrew Bartlett   2001
    55   Copyright (C) Stefan Metzmacher 2005
    6    
     6
    77   This program is free software; you can redistribute it and/or modify
    88   it under the terms of the GNU General Public License as published by
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2323
    2424#include "librpc/gen_ndr/ndr_krb5pac.h"
     25#include "librpc/gen_ndr/auth.h"
     26#include "../auth/common_auth.h"
    2527
    2628extern const char *krbtgt_attrs[];
     
    4446#define AUTH_INTERFACE_VERSION 0
    4547
    46 #define USER_INFO_CASE_INSENSITIVE_USERNAME 0x01 /* username may be in any case */
    47 #define USER_INFO_CASE_INSENSITIVE_PASSWORD 0x02 /* password may be in any case */
    48 #define USER_INFO_DONT_CHECK_UNIX_ACCOUNT   0x04 /* dont check unix account status */
    49 #define USER_INFO_INTERACTIVE_LOGON         0x08 /* dont check unix account status */
    50 
    51 enum auth_password_state {
    52         AUTH_PASSWORD_RESPONSE,
    53         AUTH_PASSWORD_HASH,
    54         AUTH_PASSWORD_PLAIN
    55 };
    56 
    57 struct auth_usersupplied_info
    58 {
    59         const char *workstation_name;
    60         struct socket_address *remote_host;
    61 
    62         uint32_t logon_parameters;
    63 
    64         bool mapped_state;
    65         /* the values the client gives us */
    66         struct {
    67                 const char *account_name;
    68                 const char *domain_name;
    69         } client, mapped;
    70 
    71         enum auth_password_state password_state;
    72 
    73         union {
    74                 struct {
    75                         DATA_BLOB lanman;
    76                         DATA_BLOB nt;
    77                 } response;
    78                 struct {
    79                         struct samr_Password *lanman;
    80                         struct samr_Password *nt;
    81                 } hash;
    82                
    83                 char *plaintext;
    84         } password;
    85         uint32_t flags;
    86 };
    87 
    88 struct auth_serversupplied_info
    89 {
    90         struct dom_sid *account_sid;
    91         struct dom_sid *primary_group_sid;
    92 
    93         size_t n_domain_groups;
    94         struct dom_sid **domain_groups;
    95 
    96         DATA_BLOB user_session_key;
    97         DATA_BLOB lm_session_key;
    98 
    99         const char *account_name;
    100         const char *domain_name;
    101 
    102         const char *full_name;
    103         const char *logon_script;
    104         const char *profile_path;
    105         const char *home_directory;
    106         const char *home_drive;
    107         const char *logon_server;
    108        
    109         NTTIME last_logon;
    110         NTTIME last_logoff;
    111         NTTIME acct_expiry;
    112         NTTIME last_password_change;
    113         NTTIME allow_password_change;
    114         NTTIME force_password_change;
    115 
    116         uint16_t logon_count;
    117         uint16_t bad_password_count;
    118 
    119         uint32_t acct_flags;
    120 
    121         bool authenticated;
    122 
    123         struct PAC_SIGNATURE_DATA pac_srv_sig, pac_kdc_sig;
    124 };
     48#define AUTH_SESSION_INFO_DEFAULT_GROUPS     0x01 /* Add the user to the default world and network groups */
     49#define AUTH_SESSION_INFO_AUTHENTICATED      0x02 /* Add the user to the 'authenticated users' group */
     50#define AUTH_SESSION_INFO_SIMPLE_PRIVILEGES  0x04 /* Use a trivial map between users and privilages, rather than a DB */
    12551
    12652struct auth_method_context;
    12753struct auth_check_password_request;
    12854struct auth_context;
     55struct auth_session_info;
     56struct ldb_dn;
    12957
    13058struct auth_operations {
     
    13664         * that.  It is not compatible with being a PDC.  */
    13765
    138         NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge);
     66        NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]);
    13967
    14068        /* Given the user supplied info, check if this backend want to handle the password checking */
     
    14775        NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx,
    14876                                   const struct auth_usersupplied_info *user_info,
    149                                    struct auth_serversupplied_info **server_info);
    150 
    151         /* Lookup a 'server info' return based only on the principal */
    152         NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx,
    153                                               struct auth_context *auth_context,
    154                                               const char *principal,
    155                                               struct auth_serversupplied_info **server_info);
     77                                   struct auth_user_info_dc **interim_info);
     78
     79        /* Lookup a 'session info interim' return based only on the principal or DN */
     80        NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
     81                                                       struct auth_context *auth_context,
     82                                                       const char *principal,
     83                                                       struct ldb_dn *user_dn,
     84                                                       struct auth_user_info_dc **interim_info);
    15685};
    15786
     
    16695struct auth_context {
    16796        struct {
    168                 /* Who set this up in the first place? */ 
     97                /* Who set this up in the first place? */
    16998                const char *set_by;
    17099
    171100                bool may_be_modified;
    172101
    173                 DATA_BLOB data; 
     102                DATA_BLOB data;
    174103        } challenge;
    175104
     
    186115        struct loadparm_context *lp_ctx;
    187116
     117        /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */
     118        struct ldb_context *sam_ctx;
     119
    188120        NTSTATUS (*check_password)(struct auth_context *auth_ctx,
    189121                                   TALLOC_CTX *mem_ctx,
    190                                    const struct auth_usersupplied_info *user_info, 
    191                                    struct auth_serversupplied_info **server_info);
    192        
    193         NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, const uint8_t **_chal);
     122                                   const struct auth_usersupplied_info *user_info,
     123                                   struct auth_user_info_dc **user_info_dc);
     124
     125        NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]);
    194126
    195127        bool (*challenge_may_be_modified)(struct auth_context *auth_ctx);
    196128
    197129        NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);
    198        
    199         NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx,
    200                                               struct auth_context *auth_context,
    201                                               const char *principal,
    202                                               struct auth_serversupplied_info **server_info);
    203 
     130
     131        NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx,
     132                                                       struct auth_context *auth_ctx,
     133                                                       const char *principal,
     134                                                       struct ldb_dn *user_dn,
     135                                                       struct auth_user_info_dc **user_info_dc);
     136
     137        NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx,
     138                                          struct auth_context *auth_context,
     139                                          struct auth_user_info_dc *user_info_dc,
     140                                          uint32_t session_info_flags,
     141                                          struct auth_session_info **session_info);
    204142};
    205143
     
    211149        int sizeof_auth_context;
    212150        int sizeof_auth_usersupplied_info;
    213         int sizeof_auth_serversupplied_info;
    214 };
    215 
    216  NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, 
     151        int sizeof_auth_user_info_dc;
     152};
     153
     154 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
    217155                           enum auth_password_state to_state,
    218156                           const struct auth_usersupplied_info *user_info_in,
     
    221159#include "auth/session.h"
    222160#include "auth/system_session_proto.h"
     161#include "libcli/security/security.h"
    223162
    224163struct ldb_message;
    225164struct ldb_context;
    226 struct ldb_dn;
    227165struct gensec_security;
    228 
    229 NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal);
     166struct cli_credentials;
     167
     168NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]);
    230169NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
    231170                            struct ldb_context *sam_ctx,
     
    237176                            bool allow_domain_trust,
    238177                            bool password_change);
    239 struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
    240 NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
     178NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
     179                                      struct ldb_val *dn_val, const bool only_childs, const char *filter,
     180                                      TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids,
     181                                      unsigned int *num_res_sids);
     182struct auth_session_info *system_session(struct loadparm_context *lp_ctx);
     183NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
    241184                                           const char *netbios_name,
    242185                                           const char *domain_name,
    243                                            struct ldb_dn *domain_dn, 
     186                                           struct ldb_dn *domain_dn,
    244187                                           struct ldb_message *msg,
    245188                                           DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key,
    246                                   struct auth_serversupplied_info **_server_info);
    247 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 
     189                                  struct auth_user_info_dc **_user_info_dc);
     190NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx,
    248191                                           struct loadparm_context *lp_ctx,
    249192                                           struct auth_session_info **_session_info) ;
    250 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status);
    251 
    252 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
     193
     194NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
    253195                                     struct tevent_context *ev,
    254196                                     struct messaging_context *msg,
    255197                                     struct loadparm_context *lp_ctx,
     198                                     struct ldb_context *sam_ctx,
    256199                                     struct auth_context **auth_ctx);
    257 
    258 NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
     200const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
     201
     202NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
    259203                             struct tevent_context *ev,
    260204                             struct messaging_context *msg,
    261205                             struct loadparm_context *lp_ctx,
    262206                             struct auth_context **auth_ctx);
     207NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx);
    263208
    264209NTSTATUS auth_check_password(struct auth_context *auth_ctx,
    265210                             TALLOC_CTX *mem_ctx,
    266                              const struct auth_usersupplied_info *user_info, 
    267                              struct auth_serversupplied_info **server_info);
    268 NTSTATUS auth_init(void);
     211                             const struct auth_usersupplied_info *user_info,
     212                             struct auth_user_info_dc **user_info_dc);
     213NTSTATUS auth4_init(void);
    269214NTSTATUS auth_register(const struct auth_operations *ops);
     215NTSTATUS server_service_auth_init(void);
    270216NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
    271                                            struct tevent_context *ev,
    272                                            struct messaging_context *msg,
    273                                            struct loadparm_context *lp_ctx,
    274                                            const char *nt4_domain,
    275                                            const char *nt4_username,
    276                                            const char *password,
    277                                            struct auth_session_info **session_info);
    278 NTSTATUS auth_check_password_recv(struct auth_check_password_request *req,
     217                                  struct tevent_context *ev,
     218                                  struct messaging_context *msg,
     219                                  struct loadparm_context *lp_ctx,
     220                                  const char *nt4_domain,
     221                                  const char *nt4_username,
     222                                  const char *password,
     223                                  const uint32_t logon_parameters,
     224                                  struct auth_session_info **session_info);
     225
     226struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
     227                                            struct tevent_context *ev,
     228                                            struct auth_context *auth_ctx,
     229                                            const struct auth_usersupplied_info *user_info);
     230NTSTATUS auth_check_password_recv(struct tevent_req *req,
    279231                                  TALLOC_CTX *mem_ctx,
    280                                   struct auth_serversupplied_info **server_info);
    281 
    282 void auth_check_password_send(struct auth_context *auth_ctx,
    283                               const struct auth_usersupplied_info *user_info,
    284                               void (*callback)(struct auth_check_password_request *req, void *private_data),
    285                               void *private_data);
     232                                  struct auth_user_info_dc **user_info_dc);
     233
     234bool auth_challenge_may_be_modified(struct auth_context *auth_ctx);
    286235NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by);
     236
     237NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
     238                                        struct auth_context *auth_ctx,
     239                                        const char *principal,
     240                                        struct ldb_dn *user_dn,
     241                                        struct auth_user_info_dc **user_info_dc);
    287242
    288243NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx,
  • vendor/current/source4/auth/credentials/credentials.c

    r414 r740  
    2525#include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
    2626#include "auth/credentials/credentials.h"
    27 #include "auth/credentials/credentials_krb5.h"
    28 #include "auth/credentials/credentials_proto.h"
    2927#include "libcli/auth/libcli_auth.h"
    3028#include "lib/events/events.h"
    3129#include "param/param.h"
     30#include "system/filesys.h"
    3231
    3332/**
     
    3837{
    3938        struct cli_credentials *cred = talloc(mem_ctx, struct cli_credentials);
    40         if (!cred) {
     39        if (cred == NULL) {
    4140                return cred;
    4241        }
    4342
    44         cred->netlogon_creds = NULL;
    45         cred->machine_account_pending = false;
    4643        cred->workstation_obtained = CRED_UNINITIALISED;
    4744        cred->username_obtained = CRED_UNINITIALISED;
     
    5148        cred->ccache_obtained = CRED_UNINITIALISED;
    5249        cred->client_gss_creds_obtained = CRED_UNINITIALISED;
     50        cred->principal_obtained = CRED_UNINITIALISED;
     51        cred->keytab_obtained = CRED_UNINITIALISED;
    5352        cred->server_gss_creds_obtained = CRED_UNINITIALISED;
    54         cred->keytab_obtained = CRED_UNINITIALISED;
    55         cred->principal_obtained = CRED_UNINITIALISED;
    5653
    5754        cred->ccache_threshold = CRED_UNINITIALISED;
    5855        cred->client_gss_creds_threshold = CRED_UNINITIALISED;
    5956
     57        cred->workstation = NULL;
     58        cred->username = NULL;
     59        cred->password = NULL;
    6060        cred->old_password = NULL;
     61        cred->domain = NULL;
     62        cred->realm = NULL;
     63        cred->principal = NULL;
     64        cred->salt_principal = NULL;
     65        cred->impersonate_principal = NULL;
     66        cred->target_service = NULL;
     67
     68        cred->bind_dn = NULL;
     69
     70        cred->nt_hash = NULL;
     71
     72        cred->lm_response.data = NULL;
     73        cred->lm_response.length = 0;
     74        cred->nt_response.data = NULL;
     75        cred->nt_response.length = 0;
     76
     77        cred->ccache = NULL;
     78        cred->client_gss_creds = NULL;
     79        cred->keytab = NULL;
     80        cred->server_gss_creds = NULL;
     81
     82        cred->workstation_cb = NULL;
     83        cred->password_cb = NULL;
     84        cred->username_cb = NULL;
     85        cred->domain_cb = NULL;
     86        cred->realm_cb = NULL;
     87        cred->principal_cb = NULL;
     88
     89        cred->priv_data = NULL;
     90
     91        cred->netlogon_creds = NULL;
     92        cred->secure_channel_type = SEC_CHAN_NULL;
     93
     94        cred->kvno = 0;
     95
     96        cred->password_last_changed_time = 0;
     97
    6198        cred->smb_krb5_context = NULL;
    62         cred->salt_principal = NULL;
     99
     100        cred->machine_account_pending = false;
     101        cred->machine_account_pending_lp_ctx = NULL;
     102
    63103        cred->machine_account = false;
    64104
    65         cred->bind_dn = NULL;
    66 
    67105        cred->tries = 3;
     106
    68107        cred->callback_running = false;
    69108
    70109        cli_credentials_set_kerberos_state(cred, CRED_AUTO_USE_KERBEROS);
    71110        cli_credentials_set_gensec_features(cred, 0);
     111        cli_credentials_set_krb_forwardable(cred, CRED_AUTO_KRB_FORWARDABLE);
    72112
    73113        return cred;
     
    94134}
    95135
     136_PUBLIC_ void cli_credentials_set_krb_forwardable(struct cli_credentials *creds,
     137                                                  enum credentials_krb_forwardable krb_forwardable)
     138{
     139        creds->krb_forwardable = krb_forwardable;
     140}
     141
    96142_PUBLIC_ enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds)
    97143{
    98144        return creds->use_kerberos;
     145}
     146
     147_PUBLIC_ enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds)
     148{
     149        return creds->krb_forwardable;
    99150}
    100151
     
    185236 * @note Return value will never be NULL except by programmer error.
    186237 */
    187 _PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
     238const char *cli_credentials_get_principal_and_obtained(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, enum credentials_obtained *obtained)
    188239{
    189240        if (cred->machine_account_pending) {
     
    201252        }
    202253
    203         if (cred->principal_obtained < cred->username_obtained) {
     254        if (cred->principal_obtained < cred->username_obtained
     255            || cred->principal_obtained < MAX(cred->domain_obtained, cred->realm_obtained)) {
    204256                if (cred->domain_obtained > cred->realm_obtained) {
     257                        *obtained = MIN(cred->domain_obtained, cred->username_obtained);
    205258                        return talloc_asprintf(mem_ctx, "%s@%s",
    206259                                               cli_credentials_get_username(cred),
    207260                                               cli_credentials_get_domain(cred));
    208261                } else {
     262                        *obtained = MIN(cred->domain_obtained, cred->username_obtained);
    209263                        return talloc_asprintf(mem_ctx, "%s@%s",
    210264                                               cli_credentials_get_username(cred),
     
    212266                }
    213267        }
     268        *obtained = cred->principal_obtained;
    214269        return talloc_reference(mem_ctx, cred->principal);
     270}
     271
     272/**
     273 * Obtain the client principal for this credentials context.
     274 * @param cred credentials context
     275 * @retval The username set on this context.
     276 * @note Return value will never be NULL except by programmer error.
     277 */
     278_PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
     279{
     280        enum credentials_obtained obtained;
     281        return cli_credentials_get_principal_and_obtained(cred, mem_ctx, &obtained);
    215282}
    216283
     
    614681{
    615682        cli_credentials_set_username(cred, "", CRED_UNINITIALISED);
    616         cli_credentials_set_domain(cred, lp_workgroup(lp_ctx), CRED_UNINITIALISED);
    617         cli_credentials_set_workstation(cred, lp_netbios_name(lp_ctx), CRED_UNINITIALISED);
    618         cli_credentials_set_realm(cred, lp_realm(lp_ctx), CRED_UNINITIALISED);
     683        cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_UNINITIALISED);
     684        cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_UNINITIALISED);
     685        cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_UNINITIALISED);
    619686}
    620687
     
    629696{
    630697        char *p;
     698        const char *error_string;
    631699
    632700        if (lp_ctx != NULL) {
     
    660728       
    661729        if (cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) {
    662                 cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE);
     730                cli_credentials_set_ccache(cred, lp_ctx, NULL, CRED_GUESS_FILE,
     731                                           &error_string);
    663732        }
    664733}
     
    691760{
    692761        cred->secure_channel_type = secure_channel_type;
     762}
     763
     764/**
     765 * Return NETLOGON secure chanel type
     766 */
     767
     768_PUBLIC_ time_t cli_credentials_get_password_last_changed_time(struct cli_credentials *cred)
     769{
     770        return cred->password_last_changed_time;
     771}
     772
     773/**
     774 * Set NETLOGON secure channel type
     775 */
     776
     777_PUBLIC_ void cli_credentials_set_password_last_changed_time(struct cli_credentials *cred,
     778                                                             time_t last_changed_time)
     779{
     780        cred->password_last_changed_time = last_changed_time;
    693781}
    694782
     
    723811        const char *username;
    724812       
     813        /* if bind dn is set it's not anonymous */
     814        if (cred->bind_dn) {
     815                return false;
     816        }
     817
    725818        if (cred->machine_account_pending) {
    726819                cli_credentials_set_machine_account(cred,
     
    760853        return (cred->tries > 0);
    761854}
     855
     856_PUBLIC_ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
     857                                              const char **username,
     858                                              const char **domain)
     859{
     860        if (cred->principal_obtained > cred->username_obtained) {
     861                *domain = talloc_strdup(mem_ctx, "");
     862                *username = cli_credentials_get_principal(cred, mem_ctx);
     863        } else {
     864                *domain = cli_credentials_get_domain(cred);
     865                *username = cli_credentials_get_username(cred);
     866        }
     867}
     868
     869/**
     870 * Read a named file, and parse it for username, domain, realm and password
     871 *
     872 * @param credentials Credentials structure on which to set the password
     873 * @param file a named file to read the details from
     874 * @param obtained This enum describes how 'specified' this password is
     875 */
     876
     877_PUBLIC_ bool cli_credentials_parse_file(struct cli_credentials *cred, const char *file, enum credentials_obtained obtained)
     878{
     879        uint16_t len = 0;
     880        char *ptr, *val, *param;
     881        char **lines;
     882        int i, numlines;
     883
     884        lines = file_lines_load(file, &numlines, 0, NULL);
     885
     886        if (lines == NULL)
     887        {
     888                /* fail if we can't open the credentials file */
     889                d_printf("ERROR: Unable to open credentials file!\n");
     890                return false;
     891        }
     892
     893        for (i = 0; i < numlines; i++) {
     894                len = strlen(lines[i]);
     895
     896                if (len == 0)
     897                        continue;
     898
     899                /* break up the line into parameter & value.
     900                 * will need to eat a little whitespace possibly */
     901                param = lines[i];
     902                if (!(ptr = strchr_m (lines[i], '=')))
     903                        continue;
     904
     905                val = ptr+1;
     906                *ptr = '\0';
     907
     908                /* eat leading white space */
     909                while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
     910                        val++;
     911
     912                if (strwicmp("password", param) == 0) {
     913                        cli_credentials_set_password(cred, val, obtained);
     914                } else if (strwicmp("username", param) == 0) {
     915                        cli_credentials_set_username(cred, val, obtained);
     916                } else if (strwicmp("domain", param) == 0) {
     917                        cli_credentials_set_domain(cred, val, obtained);
     918                } else if (strwicmp("realm", param) == 0) {
     919                        cli_credentials_set_realm(cred, val, obtained);
     920                }
     921                memset(lines[i], 0, len);
     922        }
     923
     924        talloc_free(lines);
     925
     926        return true;
     927}
     928
     929/**
     930 * Read a named file, and parse it for a password
     931 *
     932 * @param credentials Credentials structure on which to set the password
     933 * @param file a named file to read the password from
     934 * @param obtained This enum describes how 'specified' this password is
     935 */
     936
     937_PUBLIC_ bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained)
     938{
     939        int fd = open(file, O_RDONLY, 0);
     940        bool ret;
     941
     942        if (fd < 0) {
     943                fprintf(stderr, "Error opening password file %s: %s\n",
     944                                file, strerror(errno));
     945                return false;
     946        }
     947
     948        ret = cli_credentials_parse_password_fd(credentials, fd, obtained);
     949
     950        close(fd);
     951       
     952        return ret;
     953}
     954
     955
     956/**
     957 * Read a file descriptor, and parse it for a password (eg from a file or stdin)
     958 *
     959 * @param credentials Credentials structure on which to set the password
     960 * @param fd open file descriptor to read the password from
     961 * @param obtained This enum describes how 'specified' this password is
     962 */
     963
     964_PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials,
     965                                       int fd, enum credentials_obtained obtained)
     966{
     967        char *p;
     968        char pass[128];
     969
     970        for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
     971                p && p - pass < sizeof(pass);) {
     972                switch (read(fd, p, 1)) {
     973                case 1:
     974                        if (*p != '\n' && *p != '\0') {
     975                                *++p = '\0'; /* advance p, and null-terminate pass */
     976                                break;
     977                        }
     978                        /* fall through */
     979                case 0:
     980                        if (p - pass) {
     981                                *p = '\0'; /* null-terminate it, just in case... */
     982                                p = NULL; /* then force the loop condition to become false */
     983                                break;
     984                        } else {
     985                                fprintf(stderr, "Error reading password from file descriptor %d: %s\n", fd, "empty password\n");
     986                                return false;
     987                        }
     988
     989                default:
     990                        fprintf(stderr, "Error reading password from file descriptor %d: %s\n",
     991                                        fd, strerror(errno));
     992                        return false;
     993                }
     994        }
     995
     996        cli_credentials_set_password(credentials, pass, obtained);
     997        return true;
     998}
     999
     1000
  • vendor/current/source4/auth/credentials/credentials.h

    r414 r740  
    4545};
    4646
     47enum credentials_krb_forwardable {
     48        CRED_AUTO_KRB_FORWARDABLE = 0, /* Default, follow library defaults */
     49        CRED_NO_KRB_FORWARDABLE,       /* not forwardable */
     50        CRED_FORCE_KRB_FORWARDABLE     /* forwardable */
     51};
     52
    4753#define CLI_CRED_NTLM2       0x01
    4854#define CLI_CRED_NTLMv2_AUTH 0x02
     
    7783        const char *realm;
    7884        const char *principal;
    79         const char *salt_principal;
     85        char *salt_principal;
     86        char *impersonate_principal;
     87        char *target_service;
    8088
    8189        const char *bind_dn;
     
    106114        enum netr_SchannelType secure_channel_type;
    107115        int kvno;
     116        time_t password_last_changed_time;
    108117
    109118        struct smb_krb5_context *smb_krb5_context;
     
    120129        enum credentials_use_kerberos use_kerberos;
    121130
     131        /* Should we get a forwardable ticket? */
     132        enum credentials_krb_forwardable krb_forwardable;
     133
    122134        /* gensec features which should be used for connections */
    123135        uint32_t gensec_features;
     
    131143
    132144struct ldb_context;
     145struct ldb_message;
    133146struct loadparm_context;
    134147struct ccache_container;
     
    156169const char *cli_credentials_get_username(struct cli_credentials *cred);
    157170int cli_credentials_get_krb5_context(struct cli_credentials *cred,
    158                                      struct tevent_context *event_ctx,
    159171                                     struct loadparm_context *lp_ctx,
    160172                                     struct smb_krb5_context **smb_krb5_context);
     
    162174                               struct tevent_context *event_ctx,
    163175                               struct loadparm_context *lp_ctx,
    164                                struct ccache_container **ccc);
     176                               struct ccache_container **ccc,
     177                               const char **error_string);
     178int cli_credentials_get_named_ccache(struct cli_credentials *cred,
     179                                     struct tevent_context *event_ctx,
     180                                     struct loadparm_context *lp_ctx,
     181                                     char *ccache_name,
     182                                     struct ccache_container **ccc, const char **error_string);
    165183int cli_credentials_get_keytab(struct cli_credentials *cred,
    166                                struct tevent_context *event_ctx,
    167184                               struct loadparm_context *lp_ctx,
    168185                               struct keytab_container **_ktc);
     
    175192const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx);
    176193int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
    177                                          struct tevent_context *event_ctx,
    178194                                         struct loadparm_context *lp_ctx,
    179195                                         struct gssapi_creds_container **_gcc);
     
    181197                                         struct tevent_context *event_ctx,
    182198                                         struct loadparm_context *lp_ctx,
    183                                          struct gssapi_creds_container **_gcc);
     199                                         struct gssapi_creds_container **_gcc,
     200                                         const char **error_string);
    184201void cli_credentials_set_kerberos_state(struct cli_credentials *creds,
    185202                                        enum credentials_use_kerberos use_kerberos);
     203void cli_credentials_set_krb_forwardable(struct cli_credentials *creds,
     204                                         enum credentials_krb_forwardable krb_forwardable);
    186205bool cli_credentials_set_domain(struct cli_credentials *cred,
    187206                                const char *val,
     
    210229void cli_credentials_set_secure_channel_type(struct cli_credentials *cred,
    211230                                     enum netr_SchannelType secure_channel_type);
     231void cli_credentials_set_password_last_changed_time(struct cli_credentials *cred,
     232                                                             time_t last_change_time);
    212233void cli_credentials_set_netlogon_creds(struct cli_credentials *cred,
    213234                                        struct netlogon_creds_CredentialState *netlogon_creds);
     
    215236                                          struct smb_krb5_context *smb_krb5_context);
    216237NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
    217                                               struct tevent_context *event_ctx,
    218238                                              struct loadparm_context *lp_ctx,
    219239                                              const char *serviceprincipal);
     
    231251                                           const char *(*password_cb) (struct cli_credentials *));
    232252enum netr_SchannelType cli_credentials_get_secure_channel_type(struct cli_credentials *cred);
     253time_t cli_credentials_get_password_last_changed_time(struct cli_credentials *cred);
    233254void cli_credentials_set_kvno(struct cli_credentials *cred,
    234255                              int kvno);
     
    241262                                       enum credentials_obtained obtained);
    242263int cli_credentials_set_keytab_name(struct cli_credentials *cred,
    243                                     struct tevent_context *event_ctx,
    244264                                    struct loadparm_context *lp_ctx,
    245265                                    const char *keytab_name,
    246266                                    enum credentials_obtained obtained);
    247 int cli_credentials_update_keytab(struct cli_credentials *cred,
    248                                   struct tevent_context *event_ctx,
    249                                   struct loadparm_context *lp_ctx);
    250267void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features);
    251268uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds);
    252269int cli_credentials_set_ccache(struct cli_credentials *cred,
    253                                struct tevent_context *event_ctx,
    254270                               struct loadparm_context *lp_ctx,
    255271                               const char *name,
    256                                enum credentials_obtained obtained);
     272                               enum credentials_obtained obtained,
     273                               const char **error_string);
    257274bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained);
    258275bool cli_credentials_parse_password_fd(struct cli_credentials *credentials,
     
    261278                                       enum credentials_obtained obtained);
    262279void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal);
     280void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal);
     281void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal);
     282const char *cli_credentials_get_salt_principal(struct cli_credentials *cred);
     283const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred);
     284const char *cli_credentials_get_target_service(struct cli_credentials *cred);
    263285enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
     286enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds);
    264287NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
    265                                      struct tevent_context *event_ctx,
    266288                                     struct loadparm_context *lp_ctx,
    267289                                     struct ldb_context *ldb,
    268290                                     const char *base,
    269                                      const char *filter);
     291                                     const char *filter,
     292                                     char **error_string);
    270293 int cli_credentials_get_kvno(struct cli_credentials *cred);
    271294
     295
    272296#endif /* __CREDENTIALS_H__ */
  • vendor/current/source4/auth/credentials/credentials_krb5.c

    r414 r740  
    2828#include "auth/credentials/credentials_proto.h"
    2929#include "auth/credentials/credentials_krb5.h"
     30#include "auth/kerberos/kerberos_credentials.h"
     31#include "auth/kerberos/kerberos_util.h"
    3032#include "param/param.h"
    3133
    3234_PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
    33                                               struct tevent_context *event_ctx,
    3435                                     struct loadparm_context *lp_ctx,
    3536                                     struct smb_krb5_context **smb_krb5_context)
     
    4142        }
    4243
    43         ret = smb_krb5_init_context(cred, event_ctx, lp_ctx, &cred->smb_krb5_context);
     44        ret = smb_krb5_init_context(cred, NULL, lp_ctx,
     45                                    &cred->smb_krb5_context);
    4446        if (ret) {
    4547                cred->smb_krb5_context = NULL;
     
    5052}
    5153
    52 /* This needs to be called directly after the cli_credentials_init(),
    53  * otherwise we might have problems with the krb5 context already
    54  * being here.
     54/* For most predictable behaviour, this needs to be called directly after the cli_credentials_init(),
     55 * otherwise we may still have references to the old smb_krb5_context in a credential cache etc
    5556 */
    5657_PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred,
    5758                                          struct smb_krb5_context *smb_krb5_context)
    5859{
     60        if (smb_krb5_context == NULL) {
     61                talloc_unlink(cred, cred->smb_krb5_context);
     62                cred->smb_krb5_context = NULL;
     63                return NT_STATUS_OK;
     64        }
     65
    5966        if (!talloc_reference(cred, smb_krb5_context)) {
    6067                return NT_STATUS_NO_MEMORY;
     
    6572
    6673static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
    67                                     struct ccache_container *ccache,
    68                                     enum credentials_obtained obtained)
     74                                           struct ccache_container *ccache,
     75                                           enum credentials_obtained obtained,
     76                                           const char **error_string)
    6977{
    7078       
     
    8189
    8290        if (ret) {
    83                 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
    84                                                             ret, cred);
    85                 DEBUG(1,("failed to get principal from ccache: %s\n",
    86                          err_mess));
    87                 talloc_free(err_mess);
     91                (*error_string) = talloc_asprintf(cred, "failed to get principal from ccache: %s\n",
     92                                                  smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
     93                                                                             ret, cred));
    8894                return ret;
    8995        }
     
    9197        ret = krb5_unparse_name(ccache->smb_krb5_context->krb5_context, princ, &name);
    9298        if (ret) {
    93                 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, ret, cred);
    94                 DEBUG(1,("failed to unparse principal from ccache: %s\n",
    95                          err_mess));
    96                 talloc_free(err_mess);
     99                (*error_string) = talloc_asprintf(cred, "failed to unparse principal from ccache: %s\n",
     100                                                  smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
     101                                                                             ret, cred));
    97102                return ret;
    98103        }
     
    126131
    127132_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred,
    128                                         struct tevent_context *event_ctx,
    129                                struct loadparm_context *lp_ctx,
    130                                const char *name,
    131                                enum credentials_obtained obtained)
     133                                        struct loadparm_context *lp_ctx,
     134                                        const char *name,
     135                                        enum credentials_obtained obtained,
     136                                        const char **error_string)
    132137{
    133138        krb5_error_code ret;
     
    140145        ccc = talloc(cred, struct ccache_container);
    141146        if (!ccc) {
    142                 return ENOMEM;
    143         }
    144 
    145         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
     147                (*error_string) = error_message(ENOMEM);
     148                return ENOMEM;
     149        }
     150
     151        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
    146152                                               &ccc->smb_krb5_context);
    147153        if (ret) {
     154                (*error_string) = error_message(ret);
    148155                talloc_free(ccc);
    149156                return ret;
     
    151158        if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
    152159                talloc_free(ccc);
     160                (*error_string) = error_message(ENOMEM);
    153161                return ENOMEM;
    154162        }
     
    157165                ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
    158166                if (ret) {
    159                         DEBUG(1,("failed to read krb5 ccache: %s: %s\n",
    160                                  name,
    161                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     167                        (*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n",
     168                                                          name,
     169                                                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     170                                                                                     ret, ccc));
    162171                        talloc_free(ccc);
    163172                        return ret;
     
    166175                ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);
    167176                if (ret) {
    168                         DEBUG(3,("failed to read default krb5 ccache: %s\n",
    169                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     177                        (*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n",
     178                                                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     179                                                                                     ret, ccc));
    170180                        talloc_free(ccc);
    171181                        return ret;
     
    177187        ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);
    178188
    179         if (ret) {
    180                 DEBUG(3,("failed to get principal from default ccache: %s\n",
    181                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
    182                 talloc_free(ccc);               
    183                 return ret;
    184         }
    185 
    186         krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
    187 
    188         ret = cli_credentials_set_from_ccache(cred, ccc, obtained);
    189 
    190         if (ret) {
    191                 return ret;
    192         }
    193 
    194         cred->ccache = ccc;
    195         cred->ccache_obtained = obtained;
    196         talloc_steal(cred, ccc);
    197 
    198         cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
     189        if (ret == 0) {
     190                krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
     191                ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);
     192
     193                if (ret) {
     194                        (*error_string) = error_message(ret);
     195                        return ret;
     196                }
     197
     198                cred->ccache = ccc;
     199                cred->ccache_obtained = obtained;
     200                talloc_steal(cred, ccc);
     201
     202                cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
     203                return 0;
     204        }
    199205        return 0;
    200206}
     
    202208
    203209static int cli_credentials_new_ccache(struct cli_credentials *cred,
    204                                       struct tevent_context *event_ctx,
    205210                                      struct loadparm_context *lp_ctx,
    206                                       struct ccache_container **_ccc)
    207 {
     211                                      char *ccache_name,
     212                                      struct ccache_container **_ccc,
     213                                      const char **error_string)
     214{
     215        bool must_free_cc_name = false;
    208216        krb5_error_code ret;
    209217        struct ccache_container *ccc = talloc(cred, struct ccache_container);
    210         char *ccache_name;
    211218        if (!ccc) {
    212219                return ENOMEM;
    213220        }
    214221
    215         ccache_name = talloc_asprintf(ccc, "MEMORY:%p",
    216                                       ccc);
    217 
    218         if (!ccache_name) {
     222        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
     223                                               &ccc->smb_krb5_context);
     224        if (ret) {
    219225                talloc_free(ccc);
    220                 return ENOMEM;
    221         }
    222 
    223         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
    224                                                &ccc->smb_krb5_context);
    225         if (ret) {
    226                 talloc_free(ccc);
     226                (*error_string) = talloc_asprintf(cred, "Failed to get krb5_context: %s",
     227                                                  error_message(ret));
    227228                return ret;
    228229        }
    229230        if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
    230231                talloc_free(ccc);
    231                 return ENOMEM;
     232                (*error_string) = strerror(ENOMEM);
     233                return ENOMEM;
     234        }
     235
     236        if (!ccache_name) {
     237                must_free_cc_name = true;
     238                ccache_name = talloc_asprintf(ccc, "MEMORY:%p",
     239                                              ccc);
     240               
     241                if (!ccache_name) {
     242                        talloc_free(ccc);
     243                        (*error_string) = strerror(ENOMEM);
     244                        return ENOMEM;
     245                }
    232246        }
    233247
     
    235249                              &ccc->ccache);
    236250        if (ret) {
    237                 DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n",
    238                          ccache_name,
    239                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     251                (*error_string) = talloc_asprintf(cred, "failed to resolve a krb5 ccache (%s): %s\n",
     252                                                  ccache_name,
     253                                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     254                                                                             ret, ccc));
    240255                talloc_free(ccache_name);
    241256                talloc_free(ccc);
     
    243258        }
    244259
    245         talloc_set_destructor(ccc, free_mccache);
    246 
    247         talloc_free(ccache_name);
     260        if (strncasecmp(ccache_name, "MEMORY:", 7) == 0) {
     261                talloc_set_destructor(ccc, free_mccache);
     262        } else {
     263                talloc_set_destructor(ccc, free_dccache);
     264        }
     265
     266        if (must_free_cc_name) {
     267                talloc_free(ccache_name);
     268        }
    248269
    249270        *_ccc = ccc;
    250271
    251         return ret;
    252 }
    253 
    254 _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred,
    255                                         struct tevent_context *event_ctx,
    256                                struct loadparm_context *lp_ctx,
    257                                struct ccache_container **ccc)
     272        return 0;
     273}
     274
     275_PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
     276                                              struct tevent_context *event_ctx,
     277                                              struct loadparm_context *lp_ctx,
     278                                              char *ccache_name,
     279                                              struct ccache_container **ccc,
     280                                              const char **error_string)
    258281{
    259282        krb5_error_code ret;
     283        enum credentials_obtained obtained;
    260284       
    261285        if (cred->machine_account_pending) {
     
    269293        }
    270294        if (cli_credentials_is_anonymous(cred)) {
     295                (*error_string) = "Cannot get anonymous kerberos credentials";
    271296                return EINVAL;
    272297        }
    273298
    274         ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccc);
    275         if (ret) {
    276                 return ret;
    277         }
    278 
    279         ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache);
     299        ret = cli_credentials_new_ccache(cred, lp_ctx, ccache_name, ccc, error_string);
     300        if (ret) {
     301                return ret;
     302        }
     303
     304        ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string);
    280305        if (ret) {
    281306                return ret;
     
    283308
    284309        ret = cli_credentials_set_from_ccache(cred, *ccc,
    285                                               (MAX(MAX(cred->principal_obtained,
    286                                                        cred->username_obtained),
    287                                                    cred->password_obtained)));
     310                                              obtained, error_string);
    288311       
    289312        cred->ccache = *ccc;
     
    293316        }
    294317        cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
    295         return ret;
     318        return 0;
     319}
     320
     321_PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred,
     322                                        struct tevent_context *event_ctx,
     323                                        struct loadparm_context *lp_ctx,
     324                                        struct ccache_container **ccc,
     325                                        const char **error_string)
     326{
     327        return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string);
     328}
     329
     330/* We have good reason to think the ccache in these credentials is invalid - blow it away */
     331static void cli_credentials_unconditionally_invalidate_client_gss_creds(struct cli_credentials *cred)
     332{
     333        if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
     334                talloc_unlink(cred, cred->client_gss_creds);
     335                cred->client_gss_creds = NULL;
     336        }
     337        cred->client_gss_creds_obtained = CRED_UNINITIALISED;
    296338}
    297339
     
    317359}
    318360
     361/* We have good reason to think this CCACHE is invalid.  Blow it away */
     362static void cli_credentials_unconditionally_invalidate_ccache(struct cli_credentials *cred)
     363{
     364        if (cred->ccache_obtained > CRED_UNINITIALISED) {
     365                talloc_unlink(cred, cred->ccache);
     366                cred->ccache = NULL;
     367        }
     368        cred->ccache_obtained = CRED_UNINITIALISED;
     369
     370        cli_credentials_unconditionally_invalidate_client_gss_creds(cred);
     371}
     372
    319373_PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred,
    320374                                       enum credentials_obtained obtained)
     
    349403
    350404_PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
    351                                          struct tevent_context *event_ctx,
    352                                          struct loadparm_context *lp_ctx,
    353                                          struct gssapi_creds_container **_gcc)
     405                                                  struct tevent_context *event_ctx,
     406                                                  struct loadparm_context *lp_ctx,
     407                                                  struct gssapi_creds_container **_gcc,
     408                                                  const char **error_string)
    354409{
    355410        int ret = 0;
     
    366421        }
    367422
    368         ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, 
    369                                          &ccache);
     423        ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
     424                                         &ccache, error_string);
    370425        if (ret) {
    371426                DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret)));
     
    375430        gcc = talloc(cred, struct gssapi_creds_container);
    376431        if (!gcc) {
     432                (*error_string) = error_message(ENOMEM);
    377433                return ENOMEM;
    378434        }
     
    380436        maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
    381437                                        &gcc->creds);
     438        if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) {
     439                /* This CCACHE is no good.  Ensure we don't use it again */
     440                cli_credentials_unconditionally_invalidate_ccache(cred);
     441
     442                /* Now try again to get a ccache */
     443                ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
     444                                                 &ccache, error_string);
     445                if (ret) {
     446                        DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret)));
     447                        return ret;
     448                }
     449
     450                maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
     451                                                &gcc->creds);
     452
     453        }
     454
    382455        if (maj_stat) {
    383456                talloc_free(gcc);
     
    387460                        ret = EINVAL;
    388461                }
     462                (*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret));
    389463                return ret;
    390464        }
     
    409483
    410484                maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds,
    411                                                            num_ktypes, etypes);
     485                                                           num_ktypes,
     486                                                           (int32_t *) etypes);
    412487                krb5_xfree (etypes);
    413488                if (maj_stat) {
     
    418493                                ret = EINVAL;
    419494                        }
     495                        (*error_string) = talloc_asprintf(cred, "gss_krb5_set_allowable_enctypes failed: %s", error_message(ret));
    420496                        return ret;
    421497                }
     
    433509                        ret = EINVAL;
    434510                }
     511                (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret));
    435512                return ret;
    436513        }
     
    455532
    456533 int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
    457                                           struct tevent_context *event_ctx,
    458534                                          struct loadparm_context *lp_ctx,
    459535                                          gss_cred_id_t gssapi_cred,
    460                                           enum credentials_obtained obtained)
     536                                          enum credentials_obtained obtained,
     537                                          const char **error_string)
    461538{
    462539        int ret;
     
    470547        gcc = talloc(cred, struct gssapi_creds_container);
    471548        if (!gcc) {
    472                 return ENOMEM;
    473         }
    474 
    475         ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, &ccc);
     549                (*error_string) = error_message(ENOMEM);
     550                return ENOMEM;
     551        }
     552
     553        ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string);
    476554        if (ret != 0) {
    477555                return ret;
     
    486564                        ret = EINVAL;
    487565                }
     566                if (ret) {
     567                        (*error_string) = error_message(ENOMEM);
     568                }
    488569        }
    489570
    490571        if (ret == 0) {
    491                 ret = cli_credentials_set_from_ccache(cred, ccc, obtained);
     572                ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);
    492573        }
    493574        cred->ccache = ccc;
     
    510591 */
    511592_PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
    512                                         struct tevent_context *event_ctx,
    513                                struct loadparm_context *lp_ctx,
    514                                struct keytab_container **_ktc)
     593                                        struct loadparm_context *lp_ctx,
     594                                        struct keytab_container **_ktc)
    515595{
    516596        krb5_error_code ret;
    517597        struct keytab_container *ktc;
    518598        struct smb_krb5_context *smb_krb5_context;
    519         const char **enctype_strings;
    520599        TALLOC_CTX *mem_ctx;
    521600
     
    530609        }
    531610
    532         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
     611        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
    533612                                               &smb_krb5_context);
    534613        if (ret) {
     
    541620        }
    542621
    543         enctype_strings = cli_credentials_get_enctype_strings(cred);
    544        
    545622        ret = smb_krb5_create_memory_keytab(mem_ctx, cred,
    546                                             smb_krb5_context,
    547                                             enctype_strings, &ktc);
     623                                            smb_krb5_context, &ktc);
    548624        if (ret) {
    549625                talloc_free(mem_ctx);
     
    565641
    566642_PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
    567                                              struct tevent_context *event_ctx,
    568                                     struct loadparm_context *lp_ctx,
    569                                     const char *keytab_name,
    570                                     enum credentials_obtained obtained)
     643                                             struct loadparm_context *lp_ctx,
     644                                             const char *keytab_name,
     645                                             enum credentials_obtained obtained)
    571646{
    572647        krb5_error_code ret;
     
    579654        }
    580655
    581         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
     656        ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
    582657        if (ret) {
    583658                return ret;
     
    604679}
    605680
    606 _PUBLIC_ int cli_credentials_update_keytab(struct cli_credentials *cred,
    607                                            struct tevent_context *event_ctx,
    608                                   struct loadparm_context *lp_ctx)
    609 {
    610         krb5_error_code ret;
    611         struct keytab_container *ktc;
    612         struct smb_krb5_context *smb_krb5_context;
    613         const char **enctype_strings;
    614         TALLOC_CTX *mem_ctx;
    615        
    616         mem_ctx = talloc_new(cred);
    617         if (!mem_ctx) {
    618                 return ENOMEM;
    619         }
    620 
    621         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
    622         if (ret) {
    623                 talloc_free(mem_ctx);
    624                 return ret;
    625         }
    626 
    627         enctype_strings = cli_credentials_get_enctype_strings(cred);
    628        
    629         ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);
    630         if (ret != 0) {
    631                 talloc_free(mem_ctx);
    632                 return ret;
    633         }
    634 
    635         ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, ktc);
    636 
    637         talloc_free(mem_ctx);
    638         return ret;
    639 }
    640 
    641681/* Get server gss credentials (in gsskrb5, this means the keytab) */
    642682
    643683_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
    644                                                   struct tevent_context *event_ctx,
    645                                          struct loadparm_context *lp_ctx,
    646                                          struct gssapi_creds_container **_gcc)
     684                                                  struct loadparm_context *lp_ctx,
     685                                                  struct gssapi_creds_container **_gcc)
    647686{
    648687        int ret = 0;
     
    653692        TALLOC_CTX *mem_ctx;
    654693        krb5_principal princ;
    655 
    656         if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained,
    657                                                     MAX(cred->principal_obtained,
    658                                                         cred->username_obtained)))) {
    659                 *_gcc = cred->server_gss_creds;
    660                 return 0;
    661         }
    662 
    663         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
    664         if (ret) {
    665                 return ret;
    666         }
    667 
    668         ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);
    669         if (ret) {
    670                 DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
    671                 return ret;
    672         }
     694        const char *error_string;
     695        enum credentials_obtained obtained;
    673696
    674697        mem_ctx = talloc_new(cred);
     
    677700        }
    678701
    679         ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ);
    680         if (ret) {
    681                 DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n",
    682                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    683                                                     ret, mem_ctx)));
     702        ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
     703        if (ret) {
     704                return ret;
     705        }
     706
     707        ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string);
     708        if (ret) {
     709                DEBUG(1,("cli_credentials_get_server_gss_creds: making krb5 principal failed (%s)\n",
     710                         error_string));
    684711                talloc_free(mem_ctx);
     712                return ret;
     713        }
     714
     715        if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) {
     716                talloc_free(mem_ctx);
     717                *_gcc = cred->server_gss_creds;
     718                return 0;
     719        }
     720
     721        ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc);
     722        if (ret) {
     723                DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
    685724                return ret;
    686725        }
     
    732771
    733772
    734 const char **cli_credentials_get_enctype_strings(struct cli_credentials *cred)
    735 {
    736         /* If this is ever made user-configurable, we need to add code
    737          * to remove/hide the other entries from the generated
    738          * keytab */
    739         static const char *default_enctypes[] = {
    740                 "des-cbc-md5",
    741                 "aes256-cts-hmac-sha1-96",
    742                 "des3-cbc-sha1",
    743                 "arcfour-hmac-md5",
    744                 NULL
    745         };
    746         return default_enctypes;
    747 }
    748 
    749773const char *cli_credentials_get_salt_principal(struct cli_credentials *cred)
    750774{
     
    754778_PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal)
    755779{
     780        talloc_free(cred->salt_principal);
    756781        cred->salt_principal = talloc_strdup(cred, principal);
    757782}
    758783
    759 
     784/* The 'impersonate_principal' is used to allow on Kerberos principal
     785 * (and it's associated keytab etc) to impersonate another.  The
     786 * ability to do this is controlled by the KDC, but it is generally
     787 * permitted to impersonate anyone to yourself.  This allows any
     788 * member of the domain to get the groups of a user.  This is also
     789 * known as S4U2Self */
     790
     791const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred)
     792{
     793        return cred->impersonate_principal;
     794}
     795
     796_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal)
     797{
     798        talloc_free(cred->impersonate_principal);
     799        cred->impersonate_principal = talloc_strdup(cred, principal);
     800}
     801
     802/* when impersonating for S4U2Self we need to set the target principal
     803 * to ourself, as otherwise we would need additional rights.
     804 * Similarly, we may only be authorized to do general impersonation to
     805 * some particular services.
     806 *
     807 * Likewise, password changes typically require a ticket to kpasswd/realm directly, not via a TGT
     808 *
     809 * NULL means that tickets will be obtained for the krbtgt service.
     810*/
     811
     812const char *cli_credentials_get_target_service(struct cli_credentials *cred)
     813{
     814        return cred->target_service;
     815}
     816
     817_PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, const char *target_service)
     818{
     819        talloc_free(cred->target_service);
     820        cred->target_service = talloc_strdup(cred, target_service);
     821}
     822
  • vendor/current/source4/auth/credentials/credentials_krb5.h

    r414 r740  
    3434/* Manually prototyped here to avoid needing gss headers in most callers */
    3535int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
    36                                          struct tevent_context *event_ctx,
    3736                                         struct loadparm_context *lp_ctx,
    3837                                         gss_cred_id_t gssapi_cred,
    39                                          enum credentials_obtained obtained);
     38                                         enum credentials_obtained obtained,
     39                                         const char **error_string);
    4040
    4141/* Manually prototyped here to avoid needing krb5 headers in most callers */
     
    4343                                           struct cli_credentials *credentials,
    4444                                           struct smb_krb5_context *smb_krb5_context,
    45                                            krb5_principal *princ);
     45                                           krb5_principal *princ,
     46                                           enum credentials_obtained *obtained,
     47                                           const char **error_string);
     48krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx,
     49                                                       struct cli_credentials *credentials,
     50                                                       struct smb_krb5_context *smb_krb5_context,
     51                                                       krb5_principal *princ,
     52                                                       const char **error_string);
    4653       
     54void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred,
     55                                                 enum credentials_obtained obtained);
     56
    4757#endif /* __CREDENTIALS_KRB5_H__ */
  • vendor/current/source4/auth/credentials/credentials_ntlm.c

    r414 r740  
    2727#include "libcli/auth/libcli_auth.h"
    2828#include "auth/credentials/credentials.h"
    29 
    30 _PUBLIC_ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
    31                                               const char **username,
    32                                               const char **domain)
    33 {
    34         if (cred->principal_obtained > cred->username_obtained) {
    35                 *domain = talloc_strdup(mem_ctx, "");
    36                 *username = cli_credentials_get_principal(cred, mem_ctx);
    37         } else {
    38                 *domain = cli_credentials_get_domain(cred);
    39                 *username = cli_credentials_get_username(cred);
    40         }
    41 }
    4229
    4330_PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,
  • vendor/current/source4/auth/credentials/pycredentials.c

    r414 r740  
    1717*/
    1818
     19#include <Python.h>
    1920#include "includes.h"
    20 #include <Python.h>
    2121#include "pycredentials.h"
    2222#include "param/param.h"
     
    2525#include "libcli/util/pyerrors.h"
    2626#include "param/pyparam.h"
    27 
    28 #ifndef Py_RETURN_NONE
    29 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    30 #endif
     27#include <tevent.h>
    3128
    3229static PyObject *PyString_FromStringOrNULL(const char *str)
     
    197194}
    198195
     196static PyObject *py_creds_set_krb_forwardable(py_talloc_Object *self, PyObject *args)
     197{
     198        int state;
     199        if (!PyArg_ParseTuple(args, "i", &state))
     200                return NULL;
     201
     202        cli_credentials_set_krb_forwardable(PyCredentials_AsCliCredentials(self), state);
     203        Py_RETURN_NONE;
     204}
     205
    199206static PyObject *py_creds_guess(py_talloc_Object *self, PyObject *args)
    200207{
    201208        PyObject *py_lp_ctx = Py_None;
    202209        struct loadparm_context *lp_ctx;
     210        TALLOC_CTX *mem_ctx;
     211        struct cli_credentials *creds;
     212
     213        creds = PyCredentials_AsCliCredentials(self);
     214
    203215        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    204216                return NULL;
    205217
    206         lp_ctx = lp_from_py_object(py_lp_ctx);
    207         if (lp_ctx == NULL)
    208                 return NULL;
    209 
    210         cli_credentials_guess(PyCredentials_AsCliCredentials(self), lp_ctx);
     218        mem_ctx = talloc_new(NULL);
     219        if (mem_ctx == NULL) {
     220                PyErr_NoMemory();
     221                return NULL;
     222        }
     223
     224        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     225        if (lp_ctx == NULL) {
     226                talloc_free(mem_ctx);
     227                return NULL;
     228        }
     229
     230        cli_credentials_guess(creds, lp_ctx);
     231
     232        talloc_free(mem_ctx);
    211233
    212234        Py_RETURN_NONE;
     
    218240        struct loadparm_context *lp_ctx;
    219241        NTSTATUS status;
     242        struct cli_credentials *creds;
     243        TALLOC_CTX *mem_ctx;
     244
     245        creds = PyCredentials_AsCliCredentials(self);
     246
    220247        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    221248                return NULL;
    222249
    223         lp_ctx = lp_from_py_object(py_lp_ctx);
    224         if (lp_ctx == NULL)
    225                 return NULL;
    226 
    227         status = cli_credentials_set_machine_account(PyCredentials_AsCliCredentials(self), lp_ctx);
     250        mem_ctx = talloc_new(NULL);
     251        if (mem_ctx == NULL) {
     252                PyErr_NoMemory();
     253                return NULL;
     254        }
     255
     256        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     257        if (lp_ctx == NULL) {
     258                talloc_free(mem_ctx);
     259                return NULL;
     260        }
     261
     262        status = cli_credentials_set_machine_account(creds, lp_ctx);
     263        talloc_free(mem_ctx);
     264
    228265        PyErr_NTSTATUS_IS_ERR_RAISE(status);
    229266
    230267        Py_RETURN_NONE;
    231268}
     269
     270PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
     271{
     272        PyCredentialCacheContainerObject *py_ret;
     273
     274        if (ccc == NULL) {
     275                Py_RETURN_NONE;
     276        }
     277
     278        py_ret = (PyCredentialCacheContainerObject *)PyCredentialCacheContainer.tp_alloc(&PyCredentialCacheContainer, 0);
     279        if (py_ret == NULL) {
     280                PyErr_NoMemory();
     281                return NULL;
     282        }
     283        py_ret->mem_ctx = talloc_new(NULL);
     284        py_ret->ccc = talloc_reference(py_ret->mem_ctx, ccc);
     285        return (PyObject *)py_ret;
     286}
     287
     288
     289static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *args)
     290{
     291        PyObject *py_lp_ctx = Py_None;
     292        char *ccache_name;
     293        struct loadparm_context *lp_ctx;
     294        struct ccache_container *ccc;
     295        struct tevent_context *event_ctx;
     296        int ret;
     297        const char *error_string;
     298        struct cli_credentials *creds;
     299        TALLOC_CTX *mem_ctx;
     300
     301        creds = PyCredentials_AsCliCredentials(self);
     302
     303        if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
     304                return NULL;
     305
     306        mem_ctx = talloc_new(NULL);
     307        if (mem_ctx == NULL) {
     308                PyErr_NoMemory();
     309                return NULL;
     310        }
     311
     312        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     313        if (lp_ctx == NULL) {
     314                talloc_free(mem_ctx);
     315                return NULL;
     316        }
     317
     318        event_ctx = tevent_context_init(mem_ctx);
     319
     320        ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
     321                                               ccache_name, &ccc, &error_string);
     322        talloc_unlink(mem_ctx, lp_ctx);
     323        if (ret == 0) {
     324                talloc_steal(ccc, event_ctx);
     325                talloc_free(mem_ctx);
     326                return PyCredentialCacheContainer_from_ccache_container(ccc);
     327        }
     328
     329        PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
     330
     331        talloc_free(mem_ctx);
     332        return NULL;
     333}
     334
     335static PyObject *py_creds_set_gensec_features(py_talloc_Object *self, PyObject *args)
     336{
     337        unsigned int gensec_features;
     338
     339        if (!PyArg_ParseTuple(args, "I", &gensec_features))
     340                return NULL;
     341
     342        cli_credentials_set_gensec_features(PyCredentials_AsCliCredentials(self), gensec_features);
     343
     344        Py_RETURN_NONE;
     345}
     346
     347static PyObject *py_creds_get_gensec_features(py_talloc_Object *self, PyObject *args)
     348{
     349        unsigned int gensec_features;
     350
     351        gensec_features = cli_credentials_get_gensec_features(PyCredentials_AsCliCredentials(self));
     352        return PyInt_FromLong(gensec_features);
     353}
     354
    232355
    233356static PyMethodDef py_creds_methods[] = {
     
    285408        { "set_kerberos_state", (PyCFunction)py_creds_set_kerberos_state, METH_VARARGS,
    286409                NULL },
     410        { "set_krb_forwardable", (PyCFunction)py_creds_set_krb_forwardable, METH_VARARGS,
     411                NULL },
    287412        { "guess", (PyCFunction)py_creds_guess, METH_VARARGS, NULL },
    288413        { "set_machine_account", (PyCFunction)py_creds_set_machine_account, METH_VARARGS, NULL },
     414        { "get_named_ccache", (PyCFunction)py_creds_get_named_ccache, METH_VARARGS, NULL },
     415        { "set_gensec_features", (PyCFunction)py_creds_set_gensec_features, METH_VARARGS, NULL },
     416        { "get_gensec_features", (PyCFunction)py_creds_get_gensec_features, METH_NOARGS, NULL },
    289417        { NULL }
    290418};
     
    293421        .tp_name = "Credentials",
    294422        .tp_basicsize = sizeof(py_talloc_Object),
    295         .tp_dealloc = py_talloc_dealloc,
    296423        .tp_new = py_creds_new,
    297424        .tp_flags = Py_TPFLAGS_DEFAULT,
     
    299426};
    300427
     428
     429PyTypeObject PyCredentialCacheContainer = {
     430        .tp_name = "CredentialCacheContainer",
     431        .tp_basicsize = sizeof(py_talloc_Object),
     432        .tp_flags = Py_TPFLAGS_DEFAULT,
     433};
     434
    301435void initcredentials(void)
    302436{
    303437        PyObject *m;
     438        PyTypeObject *talloc_type = PyTalloc_GetObjectType();
     439        if (talloc_type == NULL)
     440                return;
     441
     442        PyCredentials.tp_base = PyCredentialCacheContainer.tp_base = talloc_type;
    304443
    305444        if (PyType_Ready(&PyCredentials) < 0)
     445                return;
     446
     447        if (PyType_Ready(&PyCredentialCacheContainer) < 0)
    306448                return;
    307449
     
    314456        PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
    315457
     458        PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE",  PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE));
     459        PyModule_AddObject(m, "NO_KRB_FORWARDABLE",    PyInt_FromLong(CRED_NO_KRB_FORWARDABLE));
     460        PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE));
     461
    316462        Py_INCREF(&PyCredentials);
    317463        PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
    318 }
     464        Py_INCREF(&PyCredentialCacheContainer);
     465        PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
     466}
  • vendor/current/source4/auth/credentials/pycredentials.h

    r414 r740  
    2121
    2222#include "auth/credentials/credentials.h"
    23 #include "pytalloc.h"
     23#include <pytalloc.h>
    2424
    25 PyAPI_DATA(PyTypeObject) PyCredentials;
     25extern PyTypeObject PyCredentials;
     26extern PyTypeObject PyCredentialCacheContainer;
     27typedef struct {
     28        PyObject_HEAD
     29        TALLOC_CTX *mem_ctx;
     30        struct ccache_container *ccc;
     31} PyCredentialCacheContainerObject;
    2632#define PyCredentials_Check(py_obj) PyObject_TypeCheck(py_obj, &PyCredentials)
    2733#define PyCredentials_AsCliCredentials(py_obj) py_talloc_get_type(py_obj, struct cli_credentials)
  • vendor/current/source4/auth/credentials/tests/simple.c

    r414 r740  
    107107struct torture_suite *torture_local_credentials(TALLOC_CTX *mem_ctx)
    108108{
    109         struct torture_suite *suite = torture_suite_create(mem_ctx,
    110                                                            "CREDENTIALS");
     109        struct torture_suite *suite = torture_suite_create(mem_ctx, "credentials");
    111110
    112111        torture_suite_add_simple_test(suite, "init", test_init);
  • vendor/current/source4/auth/gensec/cyrus_sasl.c

    r414 r740  
    2121
    2222#include "includes.h"
    23 #include "auth/auth.h"
     23#include "lib/tsocket/tsocket.h"
    2424#include "auth/credentials/credentials.h"
    2525#include "auth/gensec/gensec.h"
    2626#include "auth/gensec/gensec_proto.h"
    27 #include "lib/socket/socket.h"
    2827#include <sasl/sasl.h>
    2928
     
    3130        sasl_conn_t *conn;
    3231        int step;
     32        bool wrap;
    3333};
    3434
     
    119119        const char *service = gensec_get_target_service(gensec_security);
    120120        const char *target_name = gensec_get_target_hostname(gensec_security);
    121         struct socket_address *local_socket_addr = gensec_get_my_addr(gensec_security);
    122         struct socket_address *remote_socket_addr = gensec_get_peer_addr(gensec_security);
     121        const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security);
     122        const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security);
    123123        char *local_addr = NULL;
    124124        char *remote_addr = NULL;
     
    127127        sasl_callback_t *callbacks;
    128128
    129         gensec_sasl_state = talloc(gensec_security, struct gensec_sasl_state);
     129        gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state);
    130130        if (!gensec_sasl_state) {
    131131                return NT_STATUS_NO_MEMORY;
     
    155155        gensec_security->private_data = gensec_sasl_state;
    156156
    157         if (local_socket_addr) {
    158                 local_addr = talloc_asprintf(gensec_sasl_state, 
    159                                              "%s;%d",
    160                                              local_socket_addr->addr,
    161                                              local_socket_addr->port);
    162         }
    163 
    164         if (remote_socket_addr) {
    165                 remote_addr = talloc_asprintf(gensec_sasl_state, 
    166                                              "%s;%d",
    167                                              remote_socket_addr->addr,
    168                                              remote_socket_addr->port);
     157        if (tlocal_addr) {
     158                local_addr = talloc_asprintf(gensec_sasl_state,
     159                                "%s;%d",
     160                                tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state),
     161                                tsocket_address_inet_port(tlocal_addr));
     162        }
     163
     164        if (tremote_addr) {
     165                remote_addr = talloc_asprintf(gensec_sasl_state,
     166                                "%s;%d",
     167                                tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state),
     168                                tsocket_address_inet_port(tremote_addr));
    169169        }
    170170        gensec_sasl_state->step = 0;
     
    175175                                   &gensec_sasl_state->conn);
    176176       
    177         if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) {
     177        if (sasl_ret == SASL_OK) {
    178178                sasl_security_properties_t props;
    179179                talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose);
    180 
     180               
    181181                ZERO_STRUCT(props);
    182182                if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    183183                        props.min_ssf = 1;
     184                        props.max_ssf = 1;
     185                        props.maxbufsize = 65536;
     186                        gensec_sasl_state->wrap = true;
    184187                }
    185188                if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    186189                        props.min_ssf = 40;
    187                 }
    188                
    189                 props.max_ssf = UINT_MAX;
    190                 props.maxbufsize = 65536;
     190                        props.max_ssf = UINT_MAX;
     191                        props.maxbufsize = 65536;
     192                        gensec_sasl_state->wrap = true;
     193                }
     194
    191195                sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props);
    192                 if (sasl_ret != SASL_OK) {
    193                         return sasl_nt_status(sasl_ret);
    194                 }
    195 
    196         } else {
     196        }
     197        if (sasl_ret != SASL_OK) {
    197198                DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn)));
    198199        }
     
    263264        const char *out_data;
    264265        unsigned int out_len;
    265 
    266         int sasl_ret = sasl_encode(gensec_sasl_state->conn,
    267                                    (char*)in->data, in->length, &out_data,
    268                                    &out_len);
     266        unsigned len_permitted;
     267        int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
     268                        (const void**)&len_permitted);
     269        if (sasl_ret != SASL_OK) {
     270                return sasl_nt_status(sasl_ret);
     271        }
     272        len_permitted = MIN(len_permitted, in->length);
     273
     274        sasl_ret = sasl_encode(gensec_sasl_state->conn,
     275                               (char*)in->data, len_permitted, &out_data,
     276                               &out_len);
    269277        if (sasl_ret == SASL_OK) {
    270278                *out = data_blob_talloc(out_mem_ctx, out_data, out_len);
     
    283291                                                                      struct gensec_sasl_state);
    284292        sasl_ssf_t ssf;
    285         int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
     293        int sasl_ret;
     294
     295        /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */
     296        if (!gensec_sasl_state->wrap) {
     297                return false;
     298        }
     299       
     300        sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
    286301                        (const void**)&ssf);
    287302        if (sasl_ret != SASL_OK) {
  • vendor/current/source4/auth/gensec/gensec.c

    r414 r740  
    2222
    2323#include "includes.h"
    24 #include "auth/auth.h"
     24#include "system/network.h"
    2525#include "lib/events/events.h"
     26#include "lib/socket/socket.h"
     27#include "lib/tsocket/tsocket.h"
     28#include "../lib/util/tevent_ntstatus.h"
    2629#include "librpc/rpc/dcerpc.h"
    2730#include "auth/credentials/credentials.h"
    2831#include "auth/gensec/gensec.h"
    29 #include "auth/gensec/gensec_proto.h"
     32#include "auth/auth.h"
     33#include "auth/system_session_proto.h"
    3034#include "param/param.h"
     35#include "lib/util/tsort.h"
    3136
    3237/* the list of currently registered GENSEC backends */
     
    4348bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct gensec_security *security)
    4449{
    45         return lp_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);
     50        return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);
    4651}
    4752
     
    503508  @param gensec_security Returned GENSEC context pointer.
    504509  @note  The mem_ctx is only a parent and may be NULL.
    505   @note, the auth context is moved to be a child of the
     510  @note, the auth context is moved to be a referenced pointer of the
    506511  @ gensec_security return
    507512*/
     
    517522        }
    518523
    519         (*gensec_security) = talloc(mem_ctx, struct gensec_security);
     524        (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
    520525        NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
    521 
    522         (*gensec_security)->ops = NULL;
    523         (*gensec_security)->private_data = NULL;
    524 
    525         ZERO_STRUCT((*gensec_security)->target);
    526         ZERO_STRUCT((*gensec_security)->peer_addr);
    527         ZERO_STRUCT((*gensec_security)->my_addr);
    528 
    529         (*gensec_security)->subcontext = false;
    530         (*gensec_security)->want_features = 0;
    531526
    532527        (*gensec_security)->event_ctx = ev;
    533528        SMB_ASSERT(settings->lp_ctx != NULL);
    534529        (*gensec_security)->settings = talloc_reference(*gensec_security, settings);
    535         (*gensec_security)->auth_context = talloc_steal(*gensec_security, auth_context);
     530
     531        /* We need to reference this, not steal, as the caller may be
     532         * python, which won't like it if we steal it's object away
     533         * from it */
     534        (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context);
    536535
    537536        return NT_STATUS_OK;
     
    550549                                 struct gensec_security **gensec_security)
    551550{
    552         (*gensec_security) = talloc(mem_ctx, struct gensec_security);
     551        (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
    553552        NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
    554553
     
    593592        return status;
    594593}
     594
     595
    595596
    596597/**
     
    712713        return oid_string;
    713714}
    714        
    715 
    716 /**
    717  * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO
     715
     716/**
     717 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO
    718718 *
    719719 */
     
    982982}
    983983
    984 static void gensec_update_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te,
    985                                               struct timeval t, void *ptr)
    986 {
    987         struct gensec_update_request *req = talloc_get_type(ptr, struct gensec_update_request);
    988         req->status = req->gensec_security->ops->update(req->gensec_security, req, req->in, &req->out);
    989         req->callback.fn(req, req->callback.private_data);
    990 }
    991 
     984struct gensec_update_state {
     985        struct tevent_immediate *im;
     986        struct gensec_security *gensec_security;
     987        DATA_BLOB in;
     988        DATA_BLOB out;
     989};
     990
     991static void gensec_update_async_trigger(struct tevent_context *ctx,
     992                                        struct tevent_immediate *im,
     993                                        void *private_data);
    992994/**
    993995 * Next state function for the GENSEC state machine async version
    994  *
     996 *
     997 * @param mem_ctx The memory context for the request
     998 * @param ev The event context for the request
    995999 * @param gensec_security GENSEC State
    9961000 * @param in The request, as a DATA_BLOB
    997  * @param callback The function that will be called when the operation is
    998  *                 finished, it should return gensec_update_recv() to get output
    999  * @param private_data A private pointer that will be passed to the callback function
    1000  */
    1001 
    1002 _PUBLIC_ void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in,
    1003                                  void (*callback)(struct gensec_update_request *req, void *private_data),
    1004                                  void *private_data)
    1005 {
    1006         struct gensec_update_request *req = NULL;
    1007         struct tevent_timer *te = NULL;
    1008 
    1009         req = talloc(gensec_security, struct gensec_update_request);
    1010         if (!req) goto failed;
    1011         req->gensec_security            = gensec_security;
    1012         req->in                         = in;
    1013         req->out                        = data_blob(NULL, 0);
    1014         req->callback.fn                = callback;
    1015         req->callback.private_data      = private_data;
    1016 
    1017         te = event_add_timed(gensec_security->event_ctx, req,
    1018                              timeval_zero(),
    1019                              gensec_update_async_timed_handler, req);
    1020         if (!te) goto failed;
    1021 
    1022         return;
    1023 
    1024 failed:
    1025         talloc_free(req);
    1026         callback(NULL, private_data);
     1001 *
     1002 * @return The request handle or NULL on no memory failure
     1003 */
     1004
     1005_PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
     1006                                               struct tevent_context *ev,
     1007                                               struct gensec_security *gensec_security,
     1008                                               const DATA_BLOB in)
     1009{
     1010        struct tevent_req *req;
     1011        struct gensec_update_state *state = NULL;
     1012
     1013        req = tevent_req_create(mem_ctx, &state,
     1014                                struct gensec_update_state);
     1015        if (req == NULL) {
     1016                return NULL;
     1017        }
     1018
     1019        state->gensec_security          = gensec_security;
     1020        state->in                       = in;
     1021        state->out                      = data_blob(NULL, 0);
     1022        state->im                       = tevent_create_immediate(state);
     1023        if (tevent_req_nomem(state->im, req)) {
     1024                return tevent_req_post(req, ev);
     1025        }
     1026
     1027        tevent_schedule_immediate(state->im, ev,
     1028                                  gensec_update_async_trigger,
     1029                                  req);
     1030
     1031        return req;
     1032}
     1033
     1034static void gensec_update_async_trigger(struct tevent_context *ctx,
     1035                                        struct tevent_immediate *im,
     1036                                        void *private_data)
     1037{
     1038        struct tevent_req *req =
     1039                talloc_get_type_abort(private_data, struct tevent_req);
     1040        struct gensec_update_state *state =
     1041                tevent_req_data(req, struct gensec_update_state);
     1042        NTSTATUS status;
     1043
     1044        status = gensec_update(state->gensec_security, state,
     1045                               state->in, &state->out);
     1046        if (tevent_req_nterror(req, status)) {
     1047                return;
     1048        }
     1049
     1050        tevent_req_done(req);
    10271051}
    10281052
     
    10301054 * Next state function for the GENSEC state machine
    10311055 *
    1032  * @param req GENSEC update request state
     1056 * @param req request state
    10331057 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
    10341058 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
     
    10361060 *                or NT_STATUS_OK if the user is authenticated.
    10371061 */
    1038 _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out)
    1039 {
     1062_PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req,
     1063                                     TALLOC_CTX *out_mem_ctx,
     1064                                     DATA_BLOB *out)
     1065{
     1066        struct gensec_update_state *state =
     1067                tevent_req_data(req, struct gensec_update_state);
    10401068        NTSTATUS status;
    10411069
    1042         NT_STATUS_HAVE_NO_MEMORY(req);
    1043 
    1044         *out = req->out;
     1070        if (tevent_req_is_nterror(req, &status)) {
     1071                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     1072                        tevent_req_received(req);
     1073                        return status;
     1074                }
     1075        } else {
     1076                status = NT_STATUS_OK;
     1077        }
     1078
     1079        *out = state->out;
    10451080        talloc_steal(out_mem_ctx, out->data);
    1046         status = req->status;
    1047 
    1048         talloc_free(req);
     1081
     1082        tevent_req_received(req);
    10491083        return status;
    10501084}
     
    11621196}
    11631197
    1164 /**
    1165  * Set (and talloc_reference) local and peer socket addresses onto a socket context on the GENSEC context
     1198/**
     1199 * Set (and talloc_reference) local and peer socket addresses onto a socket
     1200 * context on the GENSEC context.
    11661201 *
    11671202 * This is so that kerberos can include these addresses in
     
    11691204 */
    11701205
    1171 _PUBLIC_ NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr)
    1172 {
    1173         gensec_security->my_addr = my_addr;
    1174         if (my_addr && !talloc_reference(gensec_security, my_addr)) {
     1206/**
     1207 * @brief Set the local gensec address.
     1208 *
     1209 * @param  gensec_security   The gensec security context to use.
     1210 *
     1211 * @param  remote       The local address to set.
     1212 *
     1213 * @return              On success NT_STATUS_OK is returned or an NT_STATUS
     1214 *                      error.
     1215 */
     1216_PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
     1217                const struct tsocket_address *local)
     1218{
     1219        TALLOC_FREE(gensec_security->local_addr);
     1220
     1221        if (local == NULL) {
     1222                return NT_STATUS_OK;
     1223        }
     1224
     1225        gensec_security->local_addr = tsocket_address_copy(local, gensec_security);
     1226        if (gensec_security->local_addr == NULL) {
    11751227                return NT_STATUS_NO_MEMORY;
    11761228        }
     1229
    11771230        return NT_STATUS_OK;
    11781231}
    11791232
    1180 _PUBLIC_ NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr)
    1181 {
    1182         gensec_security->peer_addr = peer_addr;
    1183         if (peer_addr && !talloc_reference(gensec_security, peer_addr)) {
     1233/**
     1234 * @brief Set the remote gensec address.
     1235 *
     1236 * @param  gensec_security   The gensec security context to use.
     1237 *
     1238 * @param  remote       The remote address to set.
     1239 *
     1240 * @return              On success NT_STATUS_OK is returned or an NT_STATUS
     1241 *                      error.
     1242 */
     1243_PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
     1244                const struct tsocket_address *remote)
     1245{
     1246        TALLOC_FREE(gensec_security->remote_addr);
     1247
     1248        if (remote == NULL) {
     1249                return NT_STATUS_OK;
     1250        }
     1251
     1252        gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security);
     1253        if (gensec_security->remote_addr == NULL) {
    11841254                return NT_STATUS_NO_MEMORY;
    11851255        }
     1256
    11861257        return NT_STATUS_OK;
    11871258}
    11881259
    1189 struct socket_address *gensec_get_my_addr(struct gensec_security *gensec_security)
    1190 {
    1191         if (gensec_security->my_addr) {
    1192                 return gensec_security->my_addr;
    1193         }
    1194 
    1195         /* We could add a 'set sockaddr' call, and do a lookup.  This
    1196          * would avoid needing to do system calls if nothing asks. */
    1197         return NULL;
    1198 }
    1199 
    1200 _PUBLIC_ struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security)
    1201 {
    1202         if (gensec_security->peer_addr) {
    1203                 return gensec_security->peer_addr;
    1204         }
    1205 
    1206         /* We could add a 'set sockaddr' call, and do a lookup.  This
    1207          * would avoid needing to do system calls if nothing asks.
    1208          * However, this is not appropriate for the peer addres on
    1209          * datagram sockets */
    1210         return NULL;
    1211 }
    1212 
    1213 
     1260/**
     1261 * @brief Get the local address from a gensec security context.
     1262 *
     1263 * @param  gensec_security   The security context to get the address from.
     1264 *
     1265 * @return              The address as tsocket_address which could be NULL if
     1266 *                      no address is set.
     1267 */
     1268_PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security)
     1269{
     1270        if (gensec_security == NULL) {
     1271                return NULL;
     1272        }
     1273        return gensec_security->local_addr;
     1274}
     1275
     1276/**
     1277 * @brief Get the remote address from a gensec security context.
     1278 *
     1279 * @param  gensec_security   The security context to get the address from.
     1280 *
     1281 * @return              The address as tsocket_address which could be NULL if
     1282 *                      no address is set.
     1283 */
     1284_PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security)
     1285{
     1286        if (gensec_security == NULL) {
     1287                return NULL;
     1288        }
     1289        return gensec_security->remote_addr;
     1290}
    12141291
    12151292/**
     
    12191296 */
    12201297
    1221 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
     1298_PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
    12221299{
    12231300        gensec_security->target.principal = talloc_strdup(gensec_security, principal);
     
    12351312
    12361313        return NULL;
     1314}
     1315
     1316NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx,
     1317                                      struct gensec_security *gensec_security,
     1318                                      struct auth_user_info_dc *user_info_dc,
     1319                                      struct auth_session_info **session_info)
     1320{
     1321        NTSTATUS nt_status;
     1322        uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     1323        if (user_info_dc->info->authenticated) {
     1324                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     1325        }
     1326        if (gensec_security->auth_context) {
     1327                nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context,
     1328                                                                                 user_info_dc,
     1329                                                                                 flags,
     1330                                                                                 session_info);
     1331        } else {
     1332                flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
     1333                nt_status = auth_generate_session_info(mem_ctx,
     1334                                                       NULL,
     1335                                                       NULL,
     1336                                                       user_info_dc, flags,
     1337                                                       session_info);
     1338        }
     1339        return nt_status;
    12371340}
    12381341
     
    12921395int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value)
    12931396{
    1294         return lp_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
     1397        return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
    12951398}
    12961399
    12971400bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value)
    12981401{
    1299         return lp_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
     1402        return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
    13001403}
    13011404
     
    13061409{
    13071410        static bool initialized = false;
    1308         extern NTSTATUS gensec_sasl_init(void);
    1309         extern NTSTATUS gensec_krb5_init(void);
    1310         extern NTSTATUS gensec_schannel_init(void);
    1311         extern NTSTATUS gensec_spnego_init(void);
    1312         extern NTSTATUS gensec_gssapi_init(void);
    1313         extern NTSTATUS gensec_ntlmssp_init(void);
    1314 
     1411#define _MODULE_PROTO(init) extern NTSTATUS init(void);
     1412        STATIC_gensec_MODULES_PROTO;
    13151413        init_module_fn static_init[] = { STATIC_gensec_MODULES };
    13161414        init_module_fn *shared_init;
     
    13261424        talloc_free(shared_init);
    13271425
    1328         qsort(generic_security_ops, gensec_num_backends, sizeof(*generic_security_ops), QSORT_CAST sort_gensec);
     1426        TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec);
    13291427       
    13301428        return NT_STATUS_OK;
  • vendor/current/source4/auth/gensec/gensec.h

    r414 r740  
    2727#include "libcli/util/ntstatus.h"
    2828
     29#define GENSEC_SASL_NAME_NTLMSSP "NTLM"
     30
    2931#define GENSEC_OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10"
    3032#define GENSEC_OID_SPNEGO "1.3.6.1.5.5.2"
     
    7072struct gensec_settings;
    7173struct tevent_context;
    72 
    73 struct gensec_update_request {
    74         struct gensec_security *gensec_security;
    75         void *private_data;
    76         DATA_BLOB in;
    77         DATA_BLOB out;
    78         NTSTATUS status;
    79         struct {
    80                 void (*fn)(struct gensec_update_request *req, void *private_data);
    81                 void *private_data;
    82         } callback;
    83 };
     74struct tevent_req;
    8475
    8576struct gensec_settings {
    8677        struct loadparm_context *lp_ctx;
    87         struct smb_iconv_convenience *iconv_convenience;
    8878        const char *target_hostname;
    8979};
     
    170160        uint32_t want_features;
    171161        struct tevent_context *event_ctx;
    172         struct socket_address *my_addr, *peer_addr;
     162        struct tsocket_address *local_addr, *remote_addr;
    173163        struct gensec_settings *settings;
    174164       
     
    191181struct socket_context;
    192182struct auth_context;
     183struct auth_user_info_dc;
    193184
    194185NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
     
    232223NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
    233224                       const DATA_BLOB in, DATA_BLOB *out);
    234 void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in,
    235                                  void (*callback)(struct gensec_update_request *req, void *private_data),
    236                                  void *private_data);
    237 NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out);
     225struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
     226                                      struct tevent_context *ev,
     227                                      struct gensec_security *gensec_security,
     228                                      const DATA_BLOB in);
     229NTSTATUS gensec_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out);
    238230void gensec_want_feature(struct gensec_security *gensec_security,
    239231                         uint32_t feature);
     
    251243const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string);
    252244struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security);
    253 struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security);
    254245NTSTATUS gensec_init(struct loadparm_context *lp_ctx);
    255246NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security,
     
    284275NTSTATUS gensec_session_info(struct gensec_security *gensec_security,
    285276                             struct auth_session_info **session_info);
    286 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status);
     277NTSTATUS nt_status_squash(NTSTATUS nt_status);
    287278struct netlogon_creds_CredentialState;
    288279NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
    289280                               TALLOC_CTX *mem_ctx,
    290281                               struct netlogon_creds_CredentialState **creds);
    291 NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr);
    292 NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr);
     282
     283
     284NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
     285                const struct tsocket_address *local);
     286NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
     287                const struct tsocket_address *remote);
     288const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security);
     289const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security);
    293290
    294291NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
     
    316313bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value);
    317314
     315NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal);
     316
    318317#endif /* __GENSEC_H__ */
  • vendor/current/source4/auth/gensec/gensec.pc.in

    r414 r740  
    77Name: gensec
    88Description: Generic Security Library
    9 Version: 0.0.1
    10 Libs: -L${libdir} -lgensec
     9Version: @PACKAGE_VERSION@
     10Libs: @LIB_RPATH@ -L${libdir} -lgensec
    1111Cflags: -I${includedir}  -DHAVE_IMMEDIATE_STRUCTURES=1
  • vendor/current/source4/auth/gensec/gensec_gssapi.c

    r414 r740  
    2828#include "librpc/gen_ndr/krb5pac.h"
    2929#include "auth/auth.h"
    30 #include "lib/ldb/include/ldb.h"
     30#include <ldb.h>
    3131#include "auth/auth_sam.h"
    3232#include "librpc/rpc/dcerpc.h"
     
    4141#include <gssapi/gssapi_spnego.h>
    4242#include "auth/gensec/gensec_gssapi.h"
     43#include "lib/util/util_net.h"
    4344
    4445static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security);
     
    147148        struct gensec_gssapi_state *gensec_gssapi_state;
    148149        krb5_error_code ret;
    149         struct gsskrb5_send_to_kdc send_to_kdc;
    150 
    151         gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state);
     150        const char *realm;
     151
     152        gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state);
    152153        if (!gensec_gssapi_state) {
    153154                return NT_STATUS_NO_MEMORY;
    154155        }
    155        
    156         gensec_gssapi_state->gss_exchange_count = 0;
    157         gensec_gssapi_state->max_wrap_buf_size
    158                 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);
    159                
    160         gensec_gssapi_state->sasl = false;
    161         gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
    162156
    163157        gensec_security->private_data = gensec_gssapi_state;
    164158
    165159        gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT;
     160
     161        /* TODO: Fill in channel bindings */
     162        gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
     163
    166164        gensec_gssapi_state->server_name = GSS_C_NO_NAME;
    167165        gensec_gssapi_state->client_name = GSS_C_NO_NAME;
    168         gensec_gssapi_state->lucid = NULL;
    169 
    170         /* TODO: Fill in channel bindings */
    171         gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
    172166       
    173167        gensec_gssapi_state->want_flags = 0;
     168
    174169        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
    175170                gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG;
     
    188183        }
    189184
    190         gensec_gssapi_state->got_flags = 0;
    191 
    192         gensec_gssapi_state->session_key = data_blob(NULL, 0);
    193         gensec_gssapi_state->pac = data_blob(NULL, 0);
    194 
    195         gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
    196         gensec_gssapi_state->sig_size = 0;
    197 
    198         talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
    199 
    200185        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    201186                gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG;
     
    207192                gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE;
    208193        }
     194
     195        gensec_gssapi_state->got_flags = 0;
    209196
    210197        switch (gensec_security->ops->auth_type) {
     
    218205        }
    219206
    220         send_to_kdc.func = smb_krb5_send_and_recv_func;
    221         send_to_kdc.ptr = gensec_security->event_ctx;
    222 
    223         ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
    224         if (ret) {
    225                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
    226                 talloc_free(gensec_gssapi_state);
    227                 return NT_STATUS_INTERNAL_ERROR;
    228         }
    229         if (lp_realm(gensec_security->settings->lp_ctx) && *lp_realm(gensec_security->settings->lp_ctx)) {
    230                 char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->settings->lp_ctx));
    231                 if (!upper_realm) {
    232                         DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->settings->lp_ctx)));
    233                         talloc_free(gensec_gssapi_state);
    234                         return NT_STATUS_NO_MEMORY;
    235                 }
    236                 ret = gsskrb5_set_default_realm(upper_realm);
    237                 talloc_free(upper_realm);
    238                 if (ret) {
    239                         DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n"));
    240                         talloc_free(gensec_gssapi_state);
    241                         return NT_STATUS_INTERNAL_ERROR;
    242                 }
    243         }
    244 
    245         /* don't do DNS lookups of any kind, it might/will fail for a netbios name */
    246         ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
    247         if (ret) {
    248                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
    249                 talloc_free(gensec_gssapi_state);
    250                 return NT_STATUS_INTERNAL_ERROR;
    251         }
    252 
    253         ret = smb_krb5_init_context(gensec_gssapi_state,
    254                                     gensec_security->event_ctx,
     207        gensec_gssapi_state->session_key = data_blob(NULL, 0);
     208        gensec_gssapi_state->pac = data_blob(NULL, 0);
     209
     210        ret = smb_krb5_init_context(gensec_gssapi_state,
     211                                    NULL,
    255212                                    gensec_security->settings->lp_ctx,
    256213                                    &gensec_gssapi_state->smb_krb5_context);
     
    261218                return NT_STATUS_INTERNAL_ERROR;
    262219        }
     220
     221        gensec_gssapi_state->client_cred = NULL;
     222        gensec_gssapi_state->server_cred = NULL;
     223
     224        gensec_gssapi_state->lucid = NULL;
     225
     226        gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
     227
     228        gensec_gssapi_state->sasl = false;
     229        gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
     230        gensec_gssapi_state->sasl_protection = 0;
     231
     232        gensec_gssapi_state->max_wrap_buf_size
     233                = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);
     234        gensec_gssapi_state->gss_exchange_count = 0;
     235        gensec_gssapi_state->sig_size = 0;
     236
     237        talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
     238
     239        realm = lpcfg_realm(gensec_security->settings->lp_ctx);
     240        if (realm != NULL) {
     241                ret = gsskrb5_set_default_realm(realm);
     242                if (ret) {
     243                        DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n"));
     244                        talloc_free(gensec_gssapi_state);
     245                        return NT_STATUS_INTERNAL_ERROR;
     246                }
     247        }
     248
     249        /* don't do DNS lookups of any kind, it might/will fail for a netbios name */
     250        ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
     251        if (ret) {
     252                DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
     253                talloc_free(gensec_gssapi_state);
     254                return NT_STATUS_INTERNAL_ERROR;
     255        }
     256
    263257        return NT_STATUS_OK;
    264258}
     
    286280        } else {
    287281                ret = cli_credentials_get_server_gss_creds(machine_account,
    288                                                            gensec_security->event_ctx,
    289282                                                           gensec_security->settings->lp_ctx, &gcc);
    290283                if (ret) {
     
    323316        OM_uint32 maj_stat, min_stat;
    324317        const char *hostname = gensec_get_target_hostname(gensec_security);
    325         const char *principal;
    326318        struct gssapi_creds_container *gcc;
     319        const char *error_string;
    327320
    328321        if (!hostname) {
     
    346339        gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    347340
    348         principal = gensec_get_target_principal(gensec_security);
    349         if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     341        gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
     342        if (gensec_gssapi_state->target_principal) {
    350343                name_type = GSS_C_NULL_OID;
    351344        } else {
    352                 principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",
     345                gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
    353346                                            gensec_get_target_service(gensec_security),
    354                                             hostname);
    355 
    356                 name_type = GSS_C_NT_HOSTBASED_SERVICE;
    357         }               
    358         name_token.value  = discard_const_p(uint8_t, principal);
    359         name_token.length = strlen(principal);
     347                                            hostname, lpcfg_realm(gensec_security->settings->lp_ctx));
     348
     349                name_type = GSS_C_NT_USER_NAME;
     350        }
     351        name_token.value  = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
     352        name_token.length = strlen(gensec_gssapi_state->target_principal);
    360353
    361354
     
    373366        ret = cli_credentials_get_client_gss_creds(creds,
    374367                                                   gensec_security->event_ctx,
    375                                                    gensec_security->settings->lp_ctx, &gcc);
     368                                                   gensec_security->settings->lp_ctx, &gcc, &error_string);
    376369        switch (ret) {
    377370        case 0:
    378371                break;
    379372        case KRB5KDC_ERR_PREAUTH_FAILED:
     373        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
     374                DEBUG(1, ("Wrong username or password: %s\n", error_string));
    380375                return NT_STATUS_LOGON_FAILURE;
    381376        case KRB5_KDC_UNREACH:
    382                 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
    383                 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     377                DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
     378                return NT_STATUS_NO_LOGON_SERVERS;
     379        case KRB5_CC_NOTFOUND:
     380        case KRB5_CC_END:
     381                DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string));
     382                return NT_STATUS_TIME_DIFFERENCE_AT_DC;
    384383        default:
    385                 DEBUG(1, ("Aquiring initiator credentials failed\n"));
     384                DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string));
    386385                return NT_STATUS_UNSUCCESSFUL;
    387386        }
     
    460459                case GENSEC_CLIENT:
    461460                {
     461                        struct gsskrb5_send_to_kdc send_to_kdc;
     462                        krb5_error_code ret;
     463                        send_to_kdc.func = smb_krb5_send_and_recv_func;
     464                        send_to_kdc.ptr = gensec_security->event_ctx;
     465
     466                        min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc);
     467                        if (min_stat) {
     468                                DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     469                                return NT_STATUS_INTERNAL_ERROR;
     470                        }
     471
    462472                        maj_stat = gss_init_sec_context(&min_stat,
    463473                                                        gensec_gssapi_state->client_cred->creds,
     
    476486                                gensec_gssapi_state->gss_oid = gss_oid_p;
    477487                        }
     488
     489                        send_to_kdc.func = smb_krb5_send_and_recv_func;
     490                        send_to_kdc.ptr = NULL;
     491
     492                        ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
     493                        if (ret) {
     494                                DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     495                                return NT_STATUS_INTERNAL_ERROR;
     496                        }
     497
    478498                        break;
    479499                }
     
    516536                         * is more work to do */
    517537                        if (gensec_gssapi_state->sasl) {
    518                                 /* Due to a very subtle interaction
    519                                  * with SASL and the LDAP libs, we
    520                                  * must ensure the data pointer is
    521                                  * != NULL, but the length is 0. 
    522                                  *
    523                                  * This ensures we send a 'zero
    524                                  * length' (rather than NULL) response
    525                                  */
    526                                
    527                                 if (!out->data) {
    528                                         out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");
    529                                 }
    530 
    531538                                gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG;
    532539                                return NT_STATUS_MORE_PROCESSING_REQUIRED;
     
    535542
    536543                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    537                                         DEBUG(5, ("GSSAPI Connection will be cryptographicly sealed\n"));
     544                                        DEBUG(5, ("GSSAPI Connection will be cryptographically sealed\n"));
    538545                                } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    539                                         DEBUG(5, ("GSSAPI Connection will be cryptographicly signed\n"));
     546                                        DEBUG(5, ("GSSAPI Connection will be cryptographically signed\n"));
    540547                                } else {
    541548                                        DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n"));
     
    551558                } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
    552559                        switch (min_stat) {
     560                        case KRB5KRB_AP_ERR_TKT_NYV:
     561                                DEBUG(1, ("Error with ticket to contact %s: possible clock skew between us and the KDC or target server: %s\n",
     562                                          gensec_gssapi_state->target_principal,
     563                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     564                                return NT_STATUS_TIME_DIFFERENCE_AT_DC; /* Make SPNEGO ignore us, we can't go any further here */
     565                        case KRB5KRB_AP_ERR_TKT_EXPIRED:
     566                                DEBUG(1, ("Error with ticket to contact %s: ticket is expired, possible clock skew between us and the KDC or target server: %s\n",
     567                                          gensec_gssapi_state->target_principal,
     568                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     569                                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    553570                        case KRB5_KDC_UNREACH:
    554                                 DEBUG(3, ("Cannot reach a KDC we require: %s\n",
    555                                           gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    556                                 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     571                                DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n",
     572                                          gensec_gssapi_state->target_principal,
     573                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     574                                return NT_STATUS_NO_LOGON_SERVERS; /* Make SPNEGO ignore us, we can't go any further here */
    557575                        case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
    558                                 DEBUG(3, ("Server is not registered with our KDC: %s\n",
    559                                           gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     576                                DEBUG(3, ("Server %s is not registered with our KDC: %s\n",
     577                                          gensec_gssapi_state->target_principal,
     578                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    560579                                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    561580                        case KRB5KRB_AP_ERR_MSG_TYPE:
     
    563582                                return NT_STATUS_INVALID_PARAMETER;
    564583                        default:
    565                                 DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n",
     584                                DEBUG(1, ("GSS %s Update(krb5)(%d) Update failed: %s\n",
     585                                          gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server",
    566586                                          gensec_gssapi_state->gss_exchange_count,
    567587                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     
    569589                        }
    570590                } else {
    571                         DEBUG(1, ("GSS Update(%d) failed: %s\n",
     591                        DEBUG(1, ("GSS %s Update(%d) failed: %s\n",
     592                                  gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server",
    572593                                  gensec_gssapi_state->gss_exchange_count,
    573594                                  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     
    623644                                                                     gensec_gssapi_state->max_wrap_buf_size);
    624645                        gensec_gssapi_state->sasl_protection = 0;
    625                         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    626                                 if (security_supported & NEG_SEAL) {
     646                        if (security_supported & NEG_SEAL) {
     647                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    627648                                        gensec_gssapi_state->sasl_protection |= NEG_SEAL;
    628649                                }
    629                         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    630                                 if (security_supported & NEG_SIGN) {
     650                        }
     651                        if (security_supported & NEG_SIGN) {
     652                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    631653                                        gensec_gssapi_state->sasl_protection |= NEG_SIGN;
    632654                                }
    633                         } else if (security_supported & NEG_NONE) {
     655                        }
     656                        if (security_supported & NEG_NONE) {
    634657                                gensec_gssapi_state->sasl_protection |= NEG_NONE;
    635                         } else {
    636                                 DEBUG(1, ("Remote server does not support unprotected connections"));
     658                        }
     659                        if (gensec_gssapi_state->sasl_protection == 0) {
     660                                DEBUG(1, ("Remote server does not support unprotected connections\n"));
    637661                                return NT_STATUS_ACCESS_DENIED;
    638662                        }
     
    667691
    668692                        if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    669                                 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n"));
     693                                DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically sealed\n"));
    670694                        } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    671                                 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n"));
     695                                DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically signed\n"));
    672696                        } else {
    673                                 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n"));
     697                                DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographically protection\n"));
    674698                        }
    675699
     
    768792                security_accepted = maxlength_accepted[0];
    769793                maxlength_accepted[0] = '\0';
    770                
     794
    771795                /* Rest is the proposed max wrap length */
    772796                gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0),
     
    774798
    775799                gensec_gssapi_state->sasl_protection = 0;
    776                 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    777                         if (security_accepted & NEG_SEAL) {
    778                                 gensec_gssapi_state->sasl_protection |= NEG_SEAL;
    779                         }
    780                 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    781                         if (security_accepted & NEG_SIGN) {
    782                                 gensec_gssapi_state->sasl_protection |= NEG_SIGN;
    783                         }
    784                 } else if (security_accepted & NEG_NONE) {
     800                if (security_accepted & NEG_SEAL) {
     801                        if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
     802                                DEBUG(1, ("Remote client wanted seal, but gensec refused\n"));
     803                                return NT_STATUS_ACCESS_DENIED;
     804                        }
     805                        gensec_gssapi_state->sasl_protection |= NEG_SEAL;
     806                }
     807                if (security_accepted & NEG_SIGN) {
     808                        if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
     809                                DEBUG(1, ("Remote client wanted sign, but gensec refused\n"));
     810                                return NT_STATUS_ACCESS_DENIED;
     811                        }
     812                        gensec_gssapi_state->sasl_protection |= NEG_SIGN;
     813                }
     814                if (security_accepted & NEG_NONE) {
    785815                        gensec_gssapi_state->sasl_protection |= NEG_NONE;
    786                 } else {
    787                         DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better"));
    788                         return NT_STATUS_ACCESS_DENIED;
    789816                }
    790817
     
    792819                gensec_gssapi_state->sasl_state = STAGE_DONE;
    793820                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    794                         DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n"));
     821                        DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically sealed\n"));
    795822                } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    796                         DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n"));
     823                        DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically signed\n"));
    797824                } else {
    798825                        DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n"));
     
    12311258        struct gensec_gssapi_state *gensec_gssapi_state
    12321259                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1233         struct auth_serversupplied_info *server_info = NULL;
     1260        struct auth_user_info_dc *user_info_dc = NULL;
    12341261        struct auth_session_info *session_info = NULL;
    12351262        OM_uint32 maj_stat, min_stat;
    12361263        gss_buffer_desc pac;
    12371264        DATA_BLOB pac_blob;
     1265        struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL;
     1266        struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL;
    12381267       
    12391268        if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
     
    12661295         */
    12671296        if (pac_blob.length) {
    1268                 nt_status = kerberos_pac_blob_to_server_info(mem_ctx,
    1269                                                              gensec_security->settings->iconv_convenience,
    1270                                                              pac_blob,
    1271                                                              gensec_gssapi_state->smb_krb5_context->krb5_context,
    1272                                                              &server_info);
     1297                pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
     1298                if (!pac_srv_sig) {
     1299                        talloc_free(mem_ctx);
     1300                        return NT_STATUS_NO_MEMORY;
     1301                }
     1302                pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
     1303                if (!pac_kdc_sig) {
     1304                        talloc_free(mem_ctx);
     1305                        return NT_STATUS_NO_MEMORY;
     1306                }
     1307
     1308                nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx,
     1309                                                              pac_blob,
     1310                                                              gensec_gssapi_state->smb_krb5_context->krb5_context,
     1311                                                              &user_info_dc,
     1312                                                              pac_srv_sig,
     1313                                                              pac_kdc_sig);
    12731314                if (!NT_STATUS_IS_OK(nt_status)) {
    12741315                        talloc_free(mem_ctx);
     
    13051346                        DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
    13061347                                  gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1307                         nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx,
     1348                        nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    13081349                                                                                             gensec_security->auth_context,
    13091350                                                                                             principal_string,
    1310                                                                                              &server_info);
     1351                                                                                             NULL,
     1352                                                                                             &user_info_dc);
    13111353                       
    13121354                        if (!NT_STATUS_IS_OK(nt_status)) {
     
    13221364        }
    13231365
    1324         /* references the server_info into the session_info */
    1325         nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx,
    1326                                                gensec_security->settings->lp_ctx, server_info, &session_info);
     1366        /* references the user_info_dc into the session_info */
     1367        nt_status = gensec_generate_session_info(mem_ctx, gensec_security,
     1368                                                 user_info_dc, &session_info);
    13271369        if (!NT_STATUS_IS_OK(nt_status)) {
    13281370                talloc_free(mem_ctx);
     
    13361378        }
    13371379
     1380        /* Allow torture tests to check the PAC signatures */
     1381        if (session_info->torture) {
     1382                session_info->torture->pac_srv_sig = talloc_steal(session_info->torture, pac_srv_sig);
     1383                session_info->torture->pac_kdc_sig = talloc_steal(session_info->torture, pac_kdc_sig);
     1384        }
     1385
    13381386        if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) {
    13391387                DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
    13401388        } else {
    13411389                krb5_error_code ret;
     1390                const char *error_string;
     1391
    13421392                DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n"));
    13431393                session_info->credentials = cli_credentials_init(session_info);
     
    13521402               
    13531403                ret = cli_credentials_set_client_gss_creds(session_info->credentials,
    1354                                                            gensec_security->event_ctx,
    1355                                                            gensec_security->settings->lp_ctx,
     1404                                                           gensec_security->settings->lp_ctx,
    13561405                                                           gensec_gssapi_state->delegated_cred_handle,
    1357                                                            CRED_SPECIFIED);
     1406                                                           CRED_SPECIFIED, &error_string);
    13581407                if (ret) {
    13591408                        talloc_free(mem_ctx);
     1409                        DEBUG(2,("Failed to get gss creds: %s\n", error_string));
    13601410                        return NT_STATUS_NO_MEMORY;
    13611411                }
  • vendor/current/source4/auth/gensec/gensec_gssapi.h

    r414 r740  
    6565        int gss_exchange_count;
    6666        size_t sig_size;
     67
     68        const char *target_principal;
    6769};
    6870
  • vendor/current/source4/auth/gensec/gensec_krb5.c

    r414 r740  
    2727#include "system/kerberos.h"
    2828#include "auth/kerberos/kerberos.h"
    29 #include "librpc/gen_ndr/krb5pac.h"
    3029#include "auth/auth.h"
    31 #include "lib/ldb/include/ldb.h"
    32 #include "auth/auth_sam.h"
    3330#include "lib/socket/socket.h"
     31#include "lib/tsocket/tsocket.h"
    3432#include "librpc/rpc/dcerpc.h"
    3533#include "auth/credentials/credentials.h"
    3634#include "auth/credentials/credentials_krb5.h"
     35#include "auth/kerberos/kerberos_credentials.h"
    3736#include "auth/gensec/gensec.h"
    3837#include "auth/gensec/gensec_proto.h"
    3938#include "param/param.h"
    40 #include "auth/session_proto.h"
    4139#include "auth/auth_sam_reply.h"
     40#include "lib/util/util_net.h"
    4241
    4342enum GENSEC_KRB5_STATE {
     
    9594        struct gensec_krb5_state *gensec_krb5_state;
    9695        struct cli_credentials *creds;
    97         const struct socket_address *my_addr, *peer_addr;
     96        const struct tsocket_address *tlocal_addr, *tremote_addr;
    9897        krb5_address my_krb5_addr, peer_krb5_addr;
    9998       
     
    121120
    122121        if (cli_credentials_get_krb5_context(creds,
    123                                              gensec_security->event_ctx,
    124122                                             gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) {
    125123                talloc_free(gensec_krb5_state);
     
    147145        }
    148146
    149         my_addr = gensec_get_my_addr(gensec_security);
    150         if (my_addr && my_addr->sockaddr) {
    151                 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
    152                                             my_addr->sockaddr, &my_krb5_addr);
     147        tlocal_addr = gensec_get_local_address(gensec_security);
     148        if (tlocal_addr) {
     149                ssize_t socklen;
     150                struct sockaddr_storage ss;
     151
     152                socklen = tsocket_address_bsd_sockaddr(tlocal_addr,
     153                                (struct sockaddr *) &ss,
     154                                sizeof(struct sockaddr_storage));
     155                if (socklen < 0) {
     156                        talloc_free(gensec_krb5_state);
     157                        return NT_STATUS_INTERNAL_ERROR;
     158                }
     159                ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
     160                                (const struct sockaddr *) &ss, &my_krb5_addr);
    153161                if (ret) {
    154162                        DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n",
     
    160168        }
    161169
    162         peer_addr = gensec_get_peer_addr(gensec_security);
    163         if (peer_addr && peer_addr->sockaddr) {
    164                 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
    165                                             peer_addr->sockaddr, &peer_krb5_addr);
     170        tremote_addr = gensec_get_remote_address(gensec_security);
     171        if (tremote_addr) {
     172                ssize_t socklen;
     173                struct sockaddr_storage ss;
     174
     175                socklen = tsocket_address_bsd_sockaddr(tremote_addr,
     176                                (struct sockaddr *) &ss,
     177                                sizeof(struct sockaddr_storage));
     178                if (socklen < 0) {
     179                        talloc_free(gensec_krb5_state);
     180                        return NT_STATUS_INTERNAL_ERROR;
     181                }
     182                ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
     183                                (const struct sockaddr *) &ss, &peer_krb5_addr);
    166184                if (ret) {
    167185                        DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n",
     
    175193        ret = krb5_auth_con_setaddrs(gensec_krb5_state->smb_krb5_context->krb5_context,
    176194                                     gensec_krb5_state->auth_context,
    177                                      my_addr ? &my_krb5_addr : NULL,
    178                                      peer_addr ? &peer_krb5_addr : NULL);
     195                                     tlocal_addr ? &my_krb5_addr : NULL,
     196                                     tremote_addr ? &peer_krb5_addr : NULL);
    179197        if (ret) {
    180198                DEBUG(1,("gensec_krb5_start: krb5_auth_con_setaddrs failed (%s)\n",
     
    221239        struct ccache_container *ccache_container;
    222240        const char *hostname;
    223 
     241        const char *error_string;
    224242        const char *principal;
    225243        krb5_data in_data;
     244        struct tevent_context *previous_ev;
    226245
    227246        hostname = gensec_get_target_hostname(gensec_security);
     
    264283        ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security),
    265284                                         gensec_security->event_ctx,
    266                                          gensec_security->settings->lp_ctx, &ccache_container);
     285                                         gensec_security->settings->lp_ctx, &ccache_container, &error_string);
    267286        switch (ret) {
    268287        case 0:
    269288                break;
    270289        case KRB5KDC_ERR_PREAUTH_FAILED:
     290        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
    271291                return NT_STATUS_LOGON_FAILURE;
    272292        case KRB5_KDC_UNREACH:
    273                 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
     293                DEBUG(3, ("Cannot reach a KDC we require to contact %s: %s\n", principal, error_string));
     294                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     295        case KRB5_CC_NOTFOUND:
     296        case KRB5_CC_END:
     297                DEBUG(3, ("Error preparing credentials we require to contact %s : %s\n", principal, error_string));
    274298                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    275299        default:
    276                 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_message(ret)));
     300                DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_string));
    277301                return NT_STATUS_UNSUCCESSFUL;
    278302        }
    279303        in_data.length = 0;
    280304       
    281         if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     305        /* Do this every time, in case we have weird recursive issues here */
     306        ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev);
     307        if (ret != 0) {
     308                DEBUG(1, ("gensec_krb5_start: Setting event context failed\n"));
     309                return NT_STATUS_NO_MEMORY;
     310        }
     311        if (principal) {
    282312                krb5_principal target_principal;
    283313                ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
     
    302332                                  &gensec_krb5_state->enc_ticket);
    303333        }
     334
     335        smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx);
     336
    304337        switch (ret) {
    305338        case 0:
     
    459492                struct keytab_container *keytab;
    460493                krb5_principal server_in_keytab;
     494                const char *error_string;
     495                enum credentials_obtained obtained;
    461496
    462497                if (!in.data) {
     
    466501                /* Grab the keytab, however generated */
    467502                ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security),
    468                                                  gensec_security->event_ctx,
    469503                                                 gensec_security->settings->lp_ctx, &keytab);
    470504                if (ret) {
     
    475509                ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security),
    476510                                                 gensec_krb5_state->smb_krb5_context,
    477                                                  &server_in_keytab);
     511                                                 &server_in_keytab, &obtained, &error_string);
    478512
    479513                if (ret) {
     514                        DEBUG(2,("Failed to make credentials from principal: %s\n", error_string));
    480515                        return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    481516                }
     
    569604        struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
    570605        krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context;
    571         struct auth_serversupplied_info *server_info = NULL;
     606        struct auth_user_info_dc *user_info_dc = NULL;
    572607        struct auth_session_info *session_info = NULL;
    573608        struct PAC_LOGON_INFO *logon_info;
     
    601636                          smb_get_krb5_error_message(context,
    602637                                                     ret, mem_ctx)));
     638                krb5_free_principal(context, client_principal);
    603639                talloc_free(mem_ctx);
    604640                return NT_STATUS_NO_MEMORY;
     
    614650                          smb_get_krb5_error_message(context,
    615651                                                     ret, mem_ctx)));
     652                free(principal_string);
    616653                krb5_free_principal(context, client_principal);
    617                 free(principal_string);
     654                talloc_free(mem_ctx);
    618655                return NT_STATUS_ACCESS_DENIED;
    619656        } else if (ret) {
     
    627664                                  principal_string, smb_get_krb5_error_message(context,
    628665                                                     ret, mem_ctx)));
    629                         nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx,
     666                        nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    630667                                                                                             gensec_security->auth_context,
    631668                                                                                             principal_string,
    632                                                                                              &server_info);
     669                                                                                             NULL, &user_info_dc);
    633670                        if (!NT_STATUS_IS_OK(nt_status)) {
     671                                free(principal_string);
     672                                krb5_free_principal(context, client_principal);
    634673                                talloc_free(mem_ctx);
    635674                                return nt_status;
     
    638677                        DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
    639678                                  principal_string));
     679                        free(principal_string);
     680                        krb5_free_principal(context, client_principal);
     681                        talloc_free(mem_ctx);
    640682                        return NT_STATUS_ACCESS_DENIED;
    641                 }
    642 
    643                 krb5_free_principal(context, client_principal);
    644                 free(principal_string);
    645                
    646                 if (!NT_STATUS_IS_OK(nt_status)) {
    647                         talloc_free(mem_ctx);
    648                         return nt_status;
    649683                }
    650684        } else {
    651685                /* Found pac */
    652686                union netr_Validation validation;
    653                 free(principal_string);
    654687
    655688                pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length);
    656689                if (!pac.data) {
     690                        free(principal_string);
    657691                        krb5_free_principal(context, client_principal);
    658692                        talloc_free(mem_ctx);
     
    662696                /* decode and verify the pac */
    663697                nt_status = kerberos_pac_logon_info(gensec_krb5_state,
    664                                                     gensec_security->settings->iconv_convenience,
    665698                                                    &logon_info, pac,
    666699                                                    gensec_krb5_state->smb_krb5_context->krb5_context,
     
    668701                                                    client_principal,
    669702                                                    gensec_krb5_state->ticket->ticket.authtime, NULL);
    670                 krb5_free_principal(context, client_principal);
    671703
    672704                if (!NT_STATUS_IS_OK(nt_status)) {
     705                        free(principal_string);
     706                        krb5_free_principal(context, client_principal);
    673707                        talloc_free(mem_ctx);
    674708                        return nt_status;
     
    676710
    677711                validation.sam3 = &logon_info->info3;
    678                 nt_status = make_server_info_netlogon_validation(mem_ctx,
     712                nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    679713                                                                 NULL,
    680714                                                                 3, &validation,
    681                                                                  &server_info);
     715                                                                 &user_info_dc);
    682716                if (!NT_STATUS_IS_OK(nt_status)) {
     717                        free(principal_string);
     718                        krb5_free_principal(context, client_principal);
    683719                        talloc_free(mem_ctx);
    684720                        return nt_status;
     
    686722        }
    687723
    688         /* references the server_info into the session_info */
    689         nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info);
     724        free(principal_string);
     725        krb5_free_principal(context, client_principal);
     726
     727        /* references the user_info_dc into the session_info */
     728        nt_status = gensec_generate_session_info(mem_ctx, gensec_security, user_info_dc, &session_info);
    690729
    691730        if (!NT_STATUS_IS_OK(nt_status)) {
  • vendor/current/source4/auth/gensec/pygensec.c

    r414 r740  
    1717*/
    1818
     19#include <Python.h>
    1920#include "includes.h"
    20 #include <Python.h>
    21 #include "param/param.h"
     21#include "param/pyparam.h"
    2222#include "auth/gensec/gensec.h"
     23#include "auth/credentials/pycredentials.h"
    2324#include "libcli/util/pyerrors.h"
    24 #include "pytalloc.h"
     25#include "scripting/python/modules.h"
     26#include "lib/talloc/pytalloc.h"
    2527#include <tevent.h>
    26 
    27 #ifndef Py_RETURN_NONE
    28 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    29 #endif
     28#include "librpc/rpc/pyrpc_util.h"
    3029
    3130static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args)
     
    3837                return NULL;
    3938
    40         security = (struct gensec_security *)py_talloc_get_ptr(self);
     39        security = py_talloc_get_type(self, struct gensec_security);
    4140
    4241        name = gensec_get_name_by_authtype(security, type);
     
    4746}
    4847
    49 static struct gensec_settings *settings_from_object(PyObject *object)
    50 {
    51         return NULL; /* FIXME */
     48static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object)
     49{
     50        struct gensec_settings *s;
     51        PyObject *py_hostname, *py_lp_ctx;
     52
     53        if (!PyDict_Check(object)) {
     54                PyErr_SetString(PyExc_ValueError, "settings should be a dictionary");
     55                return NULL;
     56        }
     57
     58        s = talloc_zero(mem_ctx, struct gensec_settings);
     59        if (!s) return NULL;
     60
     61        py_hostname = PyDict_GetItemString(object, "target_hostname");
     62        if (!py_hostname) {
     63                PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found");
     64                return NULL;
     65        }
     66
     67        py_lp_ctx = PyDict_GetItemString(object, "lp_ctx");
     68        if (!py_lp_ctx) {
     69                PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found");
     70                return NULL;
     71        }
     72
     73        s->target_hostname = PyString_AsString(py_hostname);
     74        s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx);
     75        return s;
    5276}
    5377
     
    6084        PyObject *py_settings;
    6185        struct tevent_context *ev;
    62 
    63         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_settings))
    64                 return NULL;
    65 
    66         settings = settings_from_object(py_settings);
    67         if (settings == NULL)
    68                 return NULL;
    69        
     86        struct gensec_security *gensec;
     87
     88        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings))
     89                return NULL;
     90
    7091        self = (py_talloc_Object*)type->tp_alloc(type, 0);
    7192        if (self == NULL) {
     
    7899                return NULL;
    79100        }
     101
     102        if (py_settings != Py_None) {
     103                settings = settings_from_object(self->talloc_ctx, py_settings);
     104                if (settings == NULL) {
     105                        PyObject_DEL(self);
     106                        return NULL;
     107                }
     108        } else {
     109                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     110                if (settings == NULL) {
     111                        PyObject_DEL(self);
     112                        return NULL;
     113                }
     114
     115                settings->lp_ctx = loadparm_init_global(true);
     116        }
     117
    80118        ev = tevent_context_init(self->talloc_ctx);
    81119        if (ev == NULL) {
     
    84122                return NULL;
    85123        }
    86         status = gensec_client_start(self->talloc_ctx,
    87                 (struct gensec_security **)&self->ptr, ev, settings);
     124
     125        status = gensec_init(settings->lp_ctx);
    88126        if (!NT_STATUS_IS_OK(status)) {
    89127                PyErr_SetNTSTATUS(status);
     
    91129                return NULL;
    92130        }
     131
     132        status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings);
     133        if (!NT_STATUS_IS_OK(status)) {
     134                PyErr_SetNTSTATUS(status);
     135                PyObject_DEL(self);
     136                return NULL;
     137        }
     138
     139        self->ptr = gensec;
     140
    93141        return (PyObject *)self;
    94142}
    95143
     144static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     145{
     146        NTSTATUS status;
     147        py_talloc_Object *self;
     148        struct gensec_settings *settings = NULL;
     149        const char *kwnames[] = { "settings", "auth_context", NULL };
     150        PyObject *py_settings = Py_None;
     151        PyObject *py_auth_context = Py_None;
     152        struct tevent_context *ev;
     153        struct gensec_security *gensec;
     154        struct auth_context *auth_context = NULL;
     155
     156        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context))
     157                return NULL;
     158
     159        self = (py_talloc_Object*)type->tp_alloc(type, 0);
     160        if (self == NULL) {
     161                PyErr_NoMemory();
     162                return NULL;
     163        }
     164        self->talloc_ctx = talloc_new(NULL);
     165        if (self->talloc_ctx == NULL) {
     166                PyErr_NoMemory();
     167                return NULL;
     168        }
     169
     170        if (py_settings != Py_None) {
     171                settings = settings_from_object(self->talloc_ctx, py_settings);
     172                if (settings == NULL) {
     173                        PyObject_DEL(self);
     174                        return NULL;
     175                }
     176        } else {
     177                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     178                if (settings == NULL) {
     179                        PyObject_DEL(self);
     180                        return NULL;
     181                }
     182
     183                settings->lp_ctx = loadparm_init_global(true);
     184        }
     185
     186        ev = tevent_context_init(self->talloc_ctx);
     187        if (ev == NULL) {
     188                PyErr_NoMemory();
     189                PyObject_Del(self);
     190                return NULL;
     191        }
     192
     193        if (py_auth_context != Py_None) {
     194                auth_context = py_talloc_get_type(py_auth_context, struct auth_context);
     195                if (!auth_context) {
     196                        PyErr_Format(PyExc_TypeError,
     197                                     "Expected auth.AuthContext for auth_context argument, got %s",
     198                                     talloc_get_name(py_talloc_get_ptr(py_auth_context)));
     199                        return NULL;
     200                }
     201        }
     202
     203        status = gensec_init(settings->lp_ctx);
     204        if (!NT_STATUS_IS_OK(status)) {
     205                PyErr_SetNTSTATUS(status);
     206                PyObject_DEL(self);
     207                return NULL;
     208        }
     209
     210        status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec);
     211        if (!NT_STATUS_IS_OK(status)) {
     212                PyErr_SetNTSTATUS(status);
     213                PyObject_DEL(self);
     214                return NULL;
     215        }
     216
     217        self->ptr = gensec;
     218
     219        return (PyObject *)self;
     220}
     221
     222static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args)
     223{
     224        PyObject *py_creds = Py_None;
     225        struct cli_credentials *creds;
     226        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     227        NTSTATUS status;
     228
     229        if (!PyArg_ParseTuple(args, "O", &py_creds))
     230                return NULL;
     231
     232        creds = PyCredentials_AsCliCredentials(py_creds);
     233        if (!creds) {
     234                PyErr_Format(PyExc_TypeError,
     235                             "Expected samba.credentaials for credentials argument got  %s",
     236                             talloc_get_name(py_talloc_get_ptr(py_creds)));
     237        }
     238
     239        status = gensec_set_credentials(security, creds);
     240        if (!NT_STATUS_IS_OK(status)) {
     241                PyErr_SetNTSTATUS(status);
     242                return NULL;
     243        }
     244
     245        Py_RETURN_NONE;
     246}
     247
    96248static PyObject *py_gensec_session_info(PyObject *self)
    97249{
    98250        NTSTATUS status;
    99         struct gensec_security *security = (struct gensec_security *)py_talloc_get_ptr(self);
     251        PyObject *py_session_info;
     252        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
    100253        struct auth_session_info *info;
     254        if (security->ops == NULL) {
     255                PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     256                return NULL;
     257        }
    101258        status = gensec_session_info(security, &info);
    102259        if (NT_STATUS_IS_ERR(status)) {
     
    105262        }
    106263
    107         /* FIXME */
     264        py_session_info = py_return_ndr_struct("samba.auth", "AuthSession",
     265                                                 info, info);
     266        return py_session_info;
     267}
     268
     269static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args)
     270{
     271        char *name;
     272        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     273        NTSTATUS status;
     274
     275        if (!PyArg_ParseTuple(args, "s", &name))
     276                return NULL;
     277
     278        status = gensec_start_mech_by_name(security, name);
     279        if (!NT_STATUS_IS_OK(status)) {
     280                PyErr_SetNTSTATUS(status);
     281                return NULL;
     282        }
     283
    108284        Py_RETURN_NONE;
     285}
     286
     287static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args)
     288{
     289        char *sasl_name;
     290        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     291        NTSTATUS status;
     292
     293        if (!PyArg_ParseTuple(args, "s", &sasl_name))
     294                return NULL;
     295
     296        status = gensec_start_mech_by_sasl_name(security, sasl_name);
     297        if (!NT_STATUS_IS_OK(status)) {
     298                PyErr_SetNTSTATUS(status);
     299                return NULL;
     300        }
     301
     302        Py_RETURN_NONE;
     303}
     304
     305static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args)
     306{
     307        int authtype, level;
     308        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     309        NTSTATUS status;
     310        if (!PyArg_ParseTuple(args, "ii", &authtype, &level))
     311                return NULL;
     312
     313        status = gensec_start_mech_by_authtype(security, authtype, level);
     314        if (!NT_STATUS_IS_OK(status)) {
     315                PyErr_SetNTSTATUS(status);
     316                return NULL;
     317        }
     318
     319        Py_RETURN_NONE;
     320}
     321
     322static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args)
     323{
     324        int feature;
     325        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     326        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     327        if (!PyArg_ParseTuple(args, "i", &feature))
     328                return NULL;
     329
     330        gensec_want_feature(security, feature);
     331
     332        Py_RETURN_NONE;
     333}
     334
     335static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args)
     336{
     337        int feature;
     338        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     339        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     340        if (!PyArg_ParseTuple(args, "i", &feature))
     341                return NULL;
     342
     343        if (gensec_have_feature(security, feature)) {
     344                return Py_True;
     345        }
     346        return Py_False;
     347}
     348
     349static PyObject *py_gensec_update(PyObject *self, PyObject *args)
     350{
     351        NTSTATUS status;
     352        TALLOC_CTX *mem_ctx;
     353        DATA_BLOB in, out;
     354        PyObject *ret, *py_in;
     355        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     356        PyObject *finished_processing;
     357
     358        if (!PyArg_ParseTuple(args, "O", &py_in))
     359                return NULL;
     360
     361        mem_ctx = talloc_new(NULL);
     362
     363        if (!PyString_Check(py_in)) {
     364                PyErr_Format(PyExc_TypeError, "expected a string");
     365                return NULL;
     366        }
     367
     368        in.data = (uint8_t *)PyString_AsString(py_in);
     369        in.length = PyString_Size(py_in);
     370
     371        status = gensec_update(security, mem_ctx, in, &out);
     372
     373        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)
     374            && !NT_STATUS_IS_OK(status)) {
     375                PyErr_SetNTSTATUS(status);
     376                talloc_free(mem_ctx);
     377                return NULL;
     378        }
     379        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     380        talloc_free(mem_ctx);
     381
     382        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     383                finished_processing = Py_False;
     384        } else {
     385                finished_processing = Py_True;
     386        }
     387
     388        return PyTuple_Pack(2, finished_processing, ret);
     389}
     390
     391static PyObject *py_gensec_wrap(PyObject *self, PyObject *args)
     392{
     393        NTSTATUS status;
     394
     395        TALLOC_CTX *mem_ctx;
     396        DATA_BLOB in, out;
     397        PyObject *ret, *py_in;
     398        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     399
     400        if (!PyArg_ParseTuple(args, "O", &py_in))
     401                return NULL;
     402
     403        mem_ctx = talloc_new(NULL);
     404
     405        if (!PyString_Check(py_in)) {
     406                PyErr_Format(PyExc_TypeError, "expected a string");
     407                return NULL;
     408        }
     409        in.data = (uint8_t *)PyString_AsString(py_in);
     410        in.length = PyString_Size(py_in);
     411
     412        status = gensec_wrap(security, mem_ctx, &in, &out);
     413
     414        if (!NT_STATUS_IS_OK(status)) {
     415                PyErr_SetNTSTATUS(status);
     416                talloc_free(mem_ctx);
     417                return NULL;
     418        }
     419
     420        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     421        talloc_free(mem_ctx);
     422        return ret;
     423}
     424
     425static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
     426{
     427        NTSTATUS status;
     428
     429        TALLOC_CTX *mem_ctx;
     430        DATA_BLOB in, out;
     431        PyObject *ret, *py_in;
     432        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     433
     434        if (!PyArg_ParseTuple(args, "O", &py_in))
     435                return NULL;
     436
     437        mem_ctx = talloc_new(NULL);
     438
     439        if (!PyString_Check(py_in)) {
     440                PyErr_Format(PyExc_TypeError, "expected a string");
     441                return NULL;
     442        }
     443
     444        in.data = (uint8_t *)PyString_AsString(py_in);
     445        in.length = PyString_Size(py_in);
     446
     447        status = gensec_unwrap(security, mem_ctx, &in, &out);
     448
     449        if (!NT_STATUS_IS_OK(status)) {
     450                PyErr_SetNTSTATUS(status);
     451                talloc_free(mem_ctx);
     452                return NULL;
     453        }
     454
     455        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     456        talloc_free(mem_ctx);
     457        return ret;
    109458}
    110459
     
    112461        { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    113462                "S.start_client(settings) -> gensec" },
    114 /*      { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    115                 "S.start_server(auth_ctx, settings) -> gensec" },*/
     463        { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
     464                "S.start_server(auth_ctx, settings) -> gensec" },
     465        { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS,
     466                "S.start_client(credentials)" },
    116467        { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
    117                 "S.session_info() -> info" },
     468                "S.session_info() -> info" },
     469        { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS,
     470        "S.start_mech_by_name(name)" },
     471        { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS,
     472        "S.start_mech_by_sasl_name(name)" },
     473        { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" },
    118474        { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS,
    119475                "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." },
     476        { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS,
     477          "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
     478        { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS,
     479          "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     480        { "update",  (PyCFunction)py_gensec_update, METH_VARARGS,
     481                "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance.  Repeat with new packets until finished is true or exception." },
     482        { "wrap",  (PyCFunction)py_gensec_wrap, METH_VARARGS,
     483                "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." },
     484        { "unwrap",  (PyCFunction)py_gensec_unwrap, METH_VARARGS,
     485                "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." },
     486
    120487        { NULL }
    121488};
     
    126493        .tp_methods = py_gensec_security_methods,
    127494        .tp_basicsize = sizeof(py_talloc_Object),
    128         .tp_dealloc = py_talloc_dealloc,
    129495};
    130496
     497void initgensec(void);
    131498void initgensec(void)
    132499{
    133500        PyObject *m;
     501
     502        Py_Security.tp_base = PyTalloc_GetObjectType();
     503        if (Py_Security.tp_base == NULL)
     504                return;
    134505
    135506        if (PyType_Ready(&Py_Security) < 0)
     
    140511                return;
    141512
     513        PyModule_AddObject(m, "FEATURE_SESSION_KEY",     PyInt_FromLong(GENSEC_FEATURE_SESSION_KEY));
     514        PyModule_AddObject(m, "FEATURE_SIGN",            PyInt_FromLong(GENSEC_FEATURE_SIGN));
     515        PyModule_AddObject(m, "FEATURE_SEAL",            PyInt_FromLong(GENSEC_FEATURE_SEAL));
     516        PyModule_AddObject(m, "FEATURE_DCE_STYLE",       PyInt_FromLong(GENSEC_FEATURE_DCE_STYLE));
     517        PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES",   PyInt_FromLong(GENSEC_FEATURE_ASYNC_REPLIES));
     518        PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE",   PyInt_FromLong(GENSEC_FEATURE_DATAGRAM_MODE));
     519        PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyInt_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER));
     520        PyModule_AddObject(m, "FEATURE_NEW_SPNEGO",      PyInt_FromLong(GENSEC_FEATURE_NEW_SPNEGO));
     521
    142522        Py_INCREF(&Py_Security);
    143523        PyModule_AddObject(m, "Security", (PyObject *)&Py_Security);
  • vendor/current/source4/auth/gensec/schannel.c

    r414 r740  
    2828#include "auth/gensec/gensec_proto.h"
    2929#include "../libcli/auth/schannel.h"
    30 #include "auth/gensec/schannel_state.h"
    3130#include "librpc/rpc/dcerpc.h"
    3231#include "param/param.h"
    33 #include "auth/session_proto.h"
    3432
    3533static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size)
    3634{
    37         return 32;
     35        struct schannel_state *state = (struct schannel_state *)gensec_security->private_data;
     36        uint32_t sig_size;
     37
     38        sig_size = netsec_outgoing_sig_size(state);
     39
     40        return sig_size;
    3841}
    3942
     
    5356        struct NL_AUTH_MESSAGE bind_schannel_ack;
    5457        struct netlogon_creds_CredentialState *creds;
    55         struct ldb_context *schannel_ldb;
    5658        const char *workstation;
    5759        const char *domain;
    58         uint32_t required_flags;
    5960
    6061        *out = data_blob(NULL, 0);
     
    9192#endif
    9293
    93                 ndr_err = ndr_push_struct_blob(out, out_mem_ctx,
    94                                                gensec_security->settings->iconv_convenience, &bind_schannel,
     94                ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel,
    9595                                               (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    9696                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    106106        case GENSEC_SERVER:
    107107
    108                 required_flags = NL_FLAG_OEM_NETBIOS_COMPUTER_NAME |
    109                                  NL_FLAG_OEM_NETBIOS_DOMAIN_NAME;
    110 
    111108                if (state->state != SCHANNEL_STATE_START) {
    112109                        /* no third leg on this protocol */
     
    115112
    116113                /* parse the schannel startup blob */
    117                 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx,
    118                         gensec_security->settings->iconv_convenience,
    119                         &bind_schannel,
     114                ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel,
    120115                        (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
    121116                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    126121                }
    127122
    128                 if (!(required_flags == (bind_schannel.Flags & required_flags))) {
    129                         return NT_STATUS_INVALID_PARAMETER;
    130                 }
    131 
    132                 workstation = bind_schannel.oem_netbios_computer.a;
    133                 domain = bind_schannel.oem_netbios_domain.a;
    134 
    135                 if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) {
    136                         DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
    137                                   domain, lp_workgroup(gensec_security->settings->lp_ctx)));
    138 
     123                if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_DOMAIN_NAME) {
     124                        domain = bind_schannel.oem_netbios_domain.a;
     125                        if (strcasecmp_m(domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)) != 0) {
     126                                DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
     127                                          domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)));
     128                                return NT_STATUS_LOGON_FAILURE;
     129                        }
     130                } else if (bind_schannel.Flags & NL_FLAG_UTF8_DNS_DOMAIN_NAME) {
     131                        domain = bind_schannel.utf8_dns_domain.u;
     132                        if (strcasecmp_m(domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)) != 0) {
     133                                DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
     134                                          domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)));
     135                                return NT_STATUS_LOGON_FAILURE;
     136                        }
     137                } else {
     138                        DEBUG(3, ("Request for schannel to without domain\n"));
    139139                        return NT_STATUS_LOGON_FAILURE;
    140140                }
    141141
    142                 schannel_ldb = schannel_db_connect(out_mem_ctx, gensec_security->event_ctx,
    143                                                    gensec_security->settings->lp_ctx);
    144                 if (!schannel_ldb) {
    145                         return NT_STATUS_ACCESS_DENIED;
    146                 }
    147                 /* pull the session key for this client */
    148                 status = schannel_fetch_session_key_ldb(schannel_ldb,
    149                                                         out_mem_ctx, workstation, &creds);
    150                 talloc_free(schannel_ldb);
     142                if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME) {
     143                        workstation = bind_schannel.oem_netbios_computer.a;
     144                } else if (bind_schannel.Flags & NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME) {
     145                        workstation = bind_schannel.utf8_netbios_computer.u;
     146                } else {
     147                        DEBUG(3, ("Request for schannel to without netbios workstation\n"));
     148                        return NT_STATUS_LOGON_FAILURE;
     149                }
     150
     151                status = schannel_get_creds_state(out_mem_ctx,
     152                                                  lpcfg_private_dir(gensec_security->settings->lp_ctx),
     153                                                  workstation, &creds);
    151154                if (!NT_STATUS_IS_OK(status)) {
    152155                        DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
     
    158161                }
    159162
    160                 state->creds = talloc_reference(state, creds);
     163                state->creds = talloc_steal(state, creds);
    161164
    162165                bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE;
     
    167170                                                            * - gd */
    168171
    169                 ndr_err = ndr_push_struct_blob(out, out_mem_ctx,
    170                                                gensec_security->settings->iconv_convenience, &bind_schannel_ack,
     172                ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack,
    171173                                               (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    172174                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    215217{
    216218        struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
    217         return auth_anonymous_session_info(state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, _session_info);
     219        return auth_anonymous_session_info(state, gensec_security->settings->lp_ctx, _session_info);
    218220}
    219221
  • vendor/current/source4/auth/gensec/socket.c

    r414 r740  
    7878                                        &unwrapped, &wrapped);
    7979                if (!NT_STATUS_IS_OK(nt_status)) {
    80                         talloc_free(mem_ctx);
    8180                        return nt_status;
    8281                }
  • vendor/current/source4/auth/gensec/spnego.c

    r414 r740  
    2929#include "auth/gensec/gensec.h"
    3030#include "auth/gensec/gensec_proto.h"
     31#include "param/param.h"
    3132
    3233enum spnego_state_position {
     
    420421
    421422        if (spnego_state->state_position == SPNEGO_SERVER_START) {
    422                 for (i=0; all_sec && all_sec[i].op; i++) {
    423                         /* optomisitic token */
    424                         if (strcmp(all_sec[i].oid, mechType[0]) == 0) {
     423                uint32_t j;
     424                for (j=0; mechType && mechType[j]; j++) {
     425                        for (i=0; all_sec && all_sec[i].op; i++) {
    425426                                nt_status = gensec_subcontext_start(spnego_state,
    426427                                                                    gensec_security,
     
    437438                                        break;
    438439                                }
    439                                
     440
     441                                if (j > 0) {
     442                                        /* no optimistic token */
     443                                        spnego_state->neg_oid = all_sec[i].oid;
     444                                        *unwrapped_out = data_blob_null;
     445                                        nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     446                                        break;
     447                                }
     448
    440449                                nt_status = gensec_update(spnego_state->sub_sec_security,
    441450                                                          out_mem_ctx,
     
    456465                                break;
    457466                        }
    458                 }
    459         }
    460        
    461         /* Having tried any optomisitc token from the client (if we
     467                        if (spnego_state->sub_sec_security) {
     468                                break;
     469                        }
     470                }
     471
     472                if (!spnego_state->sub_sec_security) {
     473                        DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n"));
     474                        return NT_STATUS_INVALID_PARAMETER;
     475                }
     476        }
     477       
     478        /* Having tried any optimistic token from the client (if we
    462479         * were the server), if we didn't get anywhere, walk our list
    463480         * in our preference order */
     
    495512                        if (spnego_state->state_position != SPNEGO_SERVER_START) {
    496513                                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) ||
     514                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS) ||
     515                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_TIME_DIFFERENCE_AT_DC) ||
    497516                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
    498517                                        /* Pretend we never started it (lets the first run find some incompatible demand) */
     
    566585        DATA_BLOB unwrapped_out = data_blob(NULL, 0);
    567586        const struct gensec_security_ops_wrapper *all_sec;
    568         const char *principal = NULL;
    569587
    570588        mechTypes = gensec_security_oids(gensec_security,
     
    633651               
    634652                if (spnego_state->state_position == SPNEGO_SERVER_START) {
    635                         /* server credentials */
    636                         struct cli_credentials *creds = gensec_get_credentials(gensec_security);
    637                         if (creds) {
    638                                 principal = cli_credentials_get_principal(creds, out_mem_ctx);
    639                         }
    640                 }
    641                 if (principal) {
    642653                        spnego_out.negTokenInit.mechListMIC
    643                                 = data_blob_string_const(principal);
     654                                = data_blob_string_const(ADS_IGNORE_PRINCIPAL);
    644655                } else {
    645656                        spnego_out.negTokenInit.mechListMIC = null_data_blob;
     
    825836                }
    826837
    827                 if (spnego.negTokenInit.targetPrincipal) {
     838                if (spnego.negTokenInit.targetPrincipal
     839                    && strcmp(spnego.negTokenInit.targetPrincipal, ADS_IGNORE_PRINCIPAL) != 0) {
    828840                        DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal));
    829                         gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal);
     841                        if (lpcfg_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     842                                gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal);
     843                        }
    830844                }
    831845
  • vendor/current/source4/auth/kerberos/kerberos.c

    r414 r740  
    3434  This version is built to use a keyblock, rather than needing the
    3535  original password.
     36
     37  The impersonate_principal is the principal if NULL, or the principal to impersonate
     38
     39  The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self)
    3640*/
    3741 krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
    38                                 krb5_principal principal, krb5_keyblock *keyblock,
    39                                 time_t *expire_time, time_t *kdc_time)
     42                                            krb5_principal principal, krb5_keyblock *keyblock,
     43                                            const char *target_service,
     44                                            krb5_get_init_creds_opt *krb_options,
     45                                            time_t *expire_time, time_t *kdc_time)
    4046{
    4147        krb5_error_code code = 0;
    4248        krb5_creds my_creds;
    43         krb5_get_init_creds_opt *options;
    44 
    45         if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
    46                 return code;
    47         }
    48 
    49         krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
    5049
    5150        if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
    52                                                  0, NULL, options))) {
     51                                                 0, target_service, krb_options))) {
    5352                return code;
    5453        }
    5554       
    5655        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
    57                 krb5_get_init_creds_opt_free(ctx, options);
    5856                krb5_free_cred_contents(ctx, &my_creds);
    5957                return code;
     
    6159       
    6260        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
    63                 krb5_get_init_creds_opt_free(ctx, options);
    6461                krb5_free_cred_contents(ctx, &my_creds);
    6562                return code;
     
    7471        }
    7572
    76         krb5_get_init_creds_opt_free(ctx, options);
    7773        krb5_free_cred_contents(ctx, &my_creds);
    7874       
     
    8379  simulate a kinit, putting the tgt in the given credentials cache.
    8480  Orignally by remus@snapserver.com
     81
     82  The impersonate_principal is the principal if NULL, or the principal to impersonate
     83
     84  The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self)
     85
    8586*/
    8687 krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
    87                                 krb5_principal principal, const char *password,
    88                                 time_t *expire_time, time_t *kdc_time)
     88                                            krb5_principal principal, const char *password,
     89                                            krb5_principal impersonate_principal, const char *target_service,
     90                                            krb5_get_init_creds_opt *krb_options,
     91                                            time_t *expire_time, time_t *kdc_time)
    8992{
    9093        krb5_error_code code = 0;
    9194        krb5_creds my_creds;
    92         krb5_get_init_creds_opt *options;
     95        krb5_creds *impersonate_creds;
     96        krb5_get_creds_opt options;
    9397
    94         if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
     98        /* If we are not impersonating, then get this ticket for the
     99         * target service, otherwise a krbtgt, and get the next ticket
     100         * for the target */
     101        if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
     102                                                 NULL, NULL,
     103                                                 0,
     104                                                 impersonate_principal ? NULL : target_service,
     105                                                 krb_options))) {
    95106                return code;
    96107        }
    97108
    98         krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
    99 
    100         if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
    101                                                  NULL,
    102                                                  NULL, 0, NULL, options))) {
    103                 return code;
    104         }
    105        
    106109        if ((code = krb5_cc_initialize(ctx, cc, principal))) {
    107                 krb5_get_init_creds_opt_free(ctx, options);
    108110                krb5_free_cred_contents(ctx, &my_creds);
    109111                return code;
     
    111113       
    112114        if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
    113                 krb5_get_init_creds_opt_free(ctx, options);
    114115                krb5_free_cred_contents(ctx, &my_creds);
    115116                return code;
     
    124125        }
    125126
    126         krb5_get_init_creds_opt_free(ctx, options);
    127127        krb5_free_cred_contents(ctx, &my_creds);
    128128       
     129        if (code == 0 && impersonate_principal) {
     130                krb5_principal target_princ;
     131                if ((code = krb5_get_creds_opt_alloc(ctx, &options))) {
     132                        return code;
     133                }
     134
     135                if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) {
     136                        krb5_get_creds_opt_free(ctx, options);
     137                        return code;
     138                }
     139
     140                if ((code = krb5_parse_name(ctx, target_service, &target_princ))) {
     141                        krb5_get_creds_opt_free(ctx, options);
     142                        return code;
     143                }
     144
     145                if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) {
     146                        krb5_get_creds_opt_free(ctx, options);
     147                        krb5_free_principal(ctx, target_princ);
     148                        return code;
     149                }
     150
     151                if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) {
     152                        krb5_free_principal(ctx, target_princ);
     153                        krb5_get_creds_opt_free(ctx, options);
     154                        return code;
     155                }
     156
     157                krb5_free_principal(ctx, target_princ);
     158
     159                code = krb5_cc_store_cred(ctx, cc, impersonate_creds);
     160                krb5_get_creds_opt_free(ctx, options);
     161                krb5_free_creds(ctx, impersonate_creds);
     162        }
     163
    129164        return 0;
    130165}
  • vendor/current/source4/auth/kerberos/kerberos.h

    r414 r740  
    2424#include "librpc/gen_ndr/krb5pac.h"
    2525
    26 struct auth_serversupplied_info;
     26struct auth_user_info_dc;
    2727struct cli_credentials;
    2828
     
    5353#define KRB5_KEY_DATA(k)        ((k)->contents)
    5454#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
     55
     56#define ENC_ALL_TYPES (ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5 |     \
     57                       ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256)
    5558
    5659#ifndef HAVE_KRB5_SET_REAL_TIME
     
    8992                                krb5_data *outbuf);
    9093bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt);
    91 int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
    92                                krb5_principal principal, const char *password,
    93                                time_t *expire_time, time_t *kdc_time);
    94 int kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
    95                                krb5_principal principal, krb5_keyblock *keyblock,
    96                                time_t *expire_time, time_t *kdc_time);
     94krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
     95                                           krb5_principal principal, const char *password,
     96                                           krb5_principal impersonate_principal, const char *target_service,
     97                                           krb5_get_init_creds_opt *krb_options,
     98                                           time_t *expire_time, time_t *kdc_time);
     99krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc,
     100                                           krb5_principal principal, krb5_keyblock *keyblock,
     101                                           const char *target_service,
     102                                           krb5_get_init_creds_opt *krb_options,
     103                                           time_t *expire_time, time_t *kdc_time);
    97104krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context,
    98105                                                        krb5_principal host_princ,
     
    103110krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
    104111char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);
    105  krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,
    106                           struct cli_credentials *credentials,
    107                           struct smb_krb5_context *smb_krb5_context,
    108                                  krb5_ccache ccache);
    109 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
    110                                            struct cli_credentials *credentials,
    111                                            struct smb_krb5_context *smb_krb5_context,
    112                                            krb5_principal *princ);
    113112NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
    114                              struct smb_iconv_convenience *iconv_convenience,
    115113                             struct PAC_DATA **pac_data_out,
    116114                             DATA_BLOB blob,
     
    122120                             krb5_error_code *k5ret);
    123121 NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,
    124                                   struct smb_iconv_convenience *iconv_convenience,
    125122                                  struct PAC_LOGON_INFO **logon_info,
    126123                                  DATA_BLOB blob,
     
    132129                                  krb5_error_code *k5ret);
    133130 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
    134                                      struct smb_iconv_convenience *iconv_convenience,
    135131                                    struct PAC_DATA *pac_data,
    136132                                    krb5_context context,
     
    139135                                    DATA_BLOB *pac);
    140136 krb5_error_code kerberos_create_pac(TALLOC_CTX *mem_ctx,
    141                                      struct smb_iconv_convenience *iconv_convenience,
    142                                      struct auth_serversupplied_info *server_info,
     137                                     struct auth_user_info_dc *user_info_dc,
    143138                                     krb5_context context,
    144139                                     const krb5_keyblock *krbtgt_keyblock,
     
    148143                                     DATA_BLOB *pac);
    149144struct loadparm_context;
     145struct ldb_message;
     146struct ldb_context;
     147uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum);
     148/* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */
     149krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap);
     150krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
     151                                       struct smb_krb5_context *smb_krb5_context,
     152                                       struct ldb_context *ldb,
     153                                       struct ldb_message *msg,
     154                                       bool delete_all_kvno,
     155                                       const char **error_string);
    150156
    151157#include "auth/kerberos/proto.h"
  • vendor/current/source4/auth/kerberos/kerberos_pac.c

    r414 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
    44   Create and parse the krb5 PAC
    5    
     5
    66   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005,2008
    77   Copyright (C) Andrew Tridgell 2001
     
    1313   the Free Software Foundation; either version 3 of the License, or
    1414   (at your option) any later version.
    15    
     15
    1616   This program is distributed in the hope that it will be useful,
    1717   but WITHOUT ANY WARRANTY; without even the implied warranty of
     
    1919   GNU General Public License for more details.
    2020
    21    
     21
    2222   You should have received a copy of the GNU General Public License
    2323   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2929#include "auth/kerberos/kerberos.h"
    3030#include "librpc/gen_ndr/ndr_krb5pac.h"
    31 #include "lib/ldb/include/ldb.h"
     31#include <ldb.h>
    3232#include "auth/auth_sam_reply.h"
    3333
    34 krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, 
     34krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
    3535                                   DATA_BLOB pac_data,
    3636                                   struct PAC_SIGNATURE_DATA *sig,
     
    5151                               &crypto);
    5252        if (ret) {
    53                 DEBUG(0,("krb5_crypto_init() failed: %s\n", 
     53                DEBUG(0,("krb5_crypto_init() failed: %s\n",
    5454                          smb_get_krb5_error_message(context, ret, mem_ctx)));
    5555                return ret;
     
    6767
    6868 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
    69                               struct smb_iconv_convenience *iconv_convenience,
    7069                              struct PAC_DATA **pac_data_out,
    7170                              DATA_BLOB blob,
     
    9594        NTTIME tgs_authtime_nttime;
    9695        krb5_principal client_principal_pac;
    97         int i;
     96        uint32_t i;
    9897
    9998        krb5_clear_error_message(context);
     
    114113        }
    115114
    116         ndr_err = ndr_pull_struct_blob(&blob, pac_data,
    117                         iconv_convenience, pac_data,
    118                        (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
     115        ndr_err = ndr_pull_struct_blob(&blob, pac_data,
     116                        pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
    119117        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    120118                status = ndr_map_error2ntstatus(ndr_err);
     
    130128        }
    131129
    132         ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw, 
    133                                        iconv_convenience, pac_data_raw,
     130        ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw,
     131                                       pac_data_raw,
    134132                                       (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW);
    135133        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    211209
    212210        /* We find the data blobs above, now we parse them to get at the exact portion we should zero */
    213         ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, 
    214                                        iconv_convenience, kdc_sig_wipe,
     211        ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe,
     212                                       kdc_sig_wipe,
    215213                                       (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    216214        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    220218                return status;
    221219        }
    222        
    223         ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, 
    224                                        iconv_convenience, srv_sig_wipe,
     220
     221        ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe,
     222                                       srv_sig_wipe,
    225223                                       (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    226224        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    234232        memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length);
    235233        memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length);
    236        
     234
    237235        /* and reencode, back into the same place it came from */
    238         ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw,
    239                                        iconv_convenience,
     236        ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw,
    240237                                       kdc_sig_wipe,
    241238                                       (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
     
    246243                return status;
    247244        }
    248         ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw,
    249                                        iconv_convenience,
     245        ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw,
    250246                                       srv_sig_wipe,
    251247                                       (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
     
    258254
    259255        /* push out the whole structure, but now with zero'ed signatures */
    260         ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
    261                                        iconv_convenience,
     256        ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw,
    262257                                       pac_data_raw,
    263258                                       (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW);
     
    270265
    271266        /* verify by service_key */
    272         ret = check_pac_checksum(mem_ctx, 
    273                                  modified_pac_blob, srv_sig_ptr, 
    274                                  context, 
     267        ret = check_pac_checksum(mem_ctx,
     268                                 modified_pac_blob, srv_sig_ptr,
     269                                 context,
    275270                                 service_keyblock);
    276271        if (ret) {
     
    284279
    285280        if (krbtgt_keyblock) {
    286                 ret = check_pac_checksum(mem_ctx, 
    287                                             srv_sig_ptr->signature, kdc_sig_ptr, 
     281                ret = check_pac_checksum(mem_ctx,
     282                                            srv_sig_ptr->signature, kdc_sig_ptr,
    288283                                            context, krbtgt_keyblock);
    289284                if (ret) {
     
    307302        }
    308303
    309         ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM, 
     304        ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM,
    310305                                    &client_principal_pac);
    311306        if (ret) {
    312                 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 
    313                           logon_name->account_name, 
     307                DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n",
     308                          logon_name->account_name,
    314309                          smb_get_krb5_error_message(context, ret, mem_ctx)));
    315310                if (k5ret) {
     
    320315
    321316        if (!krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) {
    322                 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", 
     317                DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n",
    323318                          logon_name->account_name));
     319                krb5_free_principal(context, client_principal_pac);
    324320                return NT_STATUS_ACCESS_DENIED;
    325321        }
    326        
     322
     323        krb5_free_principal(context, client_principal_pac);
     324
    327325#if 0
    328         if (strcasecmp(logon_info->info3.base.account_name.string, 
     326        if (strcasecmp(logon_info->info3.base.account_name.string,
    329327                       "Administrator")== 0) {
    330328                file_save("tmp_pac_data-admin.dat",blob.data,blob.length);
     
    333331
    334332        DEBUG(3,("Found account name from PAC: %s [%s]\n",
    335                  logon_info->info3.base.account_name.string, 
     333                 logon_info->info3.base.account_name.string,
    336334                 logon_info->info3.base.full_name.string));
    337335        *pac_data_out = pac_data;
     
    341339
    342340_PUBLIC_  NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx,
    343                                   struct smb_iconv_convenience *iconv_convenience,
    344341                                  struct PAC_LOGON_INFO **logon_info,
    345342                                  DATA_BLOB blob,
     
    348345                                  const krb5_keyblock *service_keyblock,
    349346                                  krb5_const_principal client_principal,
    350                                   time_t tgs_authtime, 
     347                                  time_t tgs_authtime,
    351348                                  krb5_error_code *k5ret)
    352349{
     
    354351        struct PAC_DATA *pac_data;
    355352        int i;
    356         nt_status = kerberos_decode_pac(mem_ctx,
    357                                         iconv_convenience,
     353        nt_status = kerberos_decode_pac(mem_ctx,
    358354                                        &pac_data,
    359355                                        blob,
     
    361357                                        krbtgt_keyblock,
    362358                                        service_keyblock,
    363                                         client_principal, 
     359                                        client_principal,
    364360                                        tgs_authtime,
    365361                                        k5ret);
     
    373369                        continue;
    374370                }
    375                 *logon_info = pac_data->buffers[i].info->logon_info.info; 
     371                *logon_info = pac_data->buffers[i].info->logon_info.info;
    376372        }
    377373        if (!*logon_info) {
     
    381377}
    382378
    383 static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx, 
     379static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
    384380                                         DATA_BLOB *pac_data,
    385381                                         struct PAC_SIGNATURE_DATA *sig,
     
    409405                                   &cksum);
    410406        if (ret) {
    411                 DEBUG(2, ("PAC Verification failed: %s\n", 
     407                DEBUG(2, ("PAC Verification failed: %s\n",
    412408                          smb_get_krb5_error_message(context, ret, mem_ctx)));
    413409        }
     
    427423
    428424 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
    429                                      struct smb_iconv_convenience *iconv_convenience,
    430425                                    struct PAC_DATA *pac_data,
    431426                                    krb5_context context,
    432427                                    const krb5_keyblock *krbtgt_keyblock,
    433428                                    const krb5_keyblock *service_keyblock,
    434                                     DATA_BLOB *pac) 
     429                                    DATA_BLOB *pac)
    435430{
    436431        NTSTATUS nt_status;
     
    448443                        continue;
    449444                }
    450                 kdc_checksum = &pac_data->buffers[i].info->kdc_cksum, 
     445                kdc_checksum = &pac_data->buffers[i].info->kdc_cksum,
    451446                ret = make_pac_checksum(mem_ctx, &zero_blob,
    452                                         kdc_checksum, 
     447                                        kdc_checksum,
    453448                                        context, krbtgt_keyblock);
    454449                if (ret) {
    455                         DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 
     450                        DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
    456451                                  smb_get_krb5_error_message(context, ret, mem_ctx)));
    457452                        talloc_free(pac_data);
     
    459454                }
    460455        }
    461        
     456
    462457        for (i=0; i < pac_data->num_buffers; i++) {
    463458                if (pac_data->buffers[i].type != PAC_TYPE_SRV_CHECKSUM) {
    464459                        continue;
    465460                }
    466                 srv_checksum = &pac_data->buffers[i].info->srv_cksum; 
    467                 ret = make_pac_checksum(mem_ctx, &zero_blob, 
    468                                         srv_checksum, 
     461                srv_checksum = &pac_data->buffers[i].info->srv_cksum;
     462                ret = make_pac_checksum(mem_ctx, &zero_blob,
     463                                        srv_checksum,
    469464                                        context, service_keyblock);
    470465                if (ret) {
    471                         DEBUG(2, ("making service PAC checksum failed: %s\n", 
     466                        DEBUG(2, ("making service PAC checksum failed: %s\n",
    472467                                  smb_get_krb5_error_message(context, ret, mem_ctx)));
    473468                        talloc_free(pac_data);
     
    489484        memset(srv_checksum->signature.data, '\0', srv_checksum->signature.length);
    490485
    491         ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx,
    492                                        iconv_convenience,
     486        ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx,
    493487                                       pac_data,
    494488                                       (ndr_push_flags_fn_t)ndr_push_PAC_DATA);
     
    507501        ret = make_pac_checksum(mem_ctx, &srv_checksum->signature, kdc_checksum, context, krbtgt_keyblock);
    508502        if (ret) {
    509                 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 
     503                DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
    510504                          smb_get_krb5_error_message(context, ret, mem_ctx)));
    511505                talloc_free(pac_data);
     
    514508
    515509        /* And push it out again, this time to the world.  This relies on determanistic pointer values */
    516         ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx,
    517                                        iconv_convenience,
     510        ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx,
    518511                                       pac_data,
    519512                                       (ndr_push_flags_fn_t)ndr_push_PAC_DATA);
     
    532525
    533526 krb5_error_code kerberos_create_pac(TALLOC_CTX *mem_ctx,
    534                                      struct smb_iconv_convenience *iconv_convenience,
    535                                      struct auth_serversupplied_info *server_info,
     527                                     struct auth_user_info_dc *user_info_dc,
    536528                                     krb5_context context,
    537529                                     const krb5_keyblock *krbtgt_keyblock,
     
    553545
    554546        char *name;
    555                
     547
    556548        enum {
    557549                PAC_BUF_LOGON_INFO = 0,
     
    569561        pac_data->version = 0;
    570562
    571         pac_data->buffers = talloc_array(pac_data, 
     563        pac_data->buffers = talloc_array(pac_data,
    572564                                         struct PAC_BUFFER,
    573565                                         pac_data->num_buffers);
     
    621613                return ENOMEM;
    622614        }
    623         nt_status = auth_convert_server_info_saminfo3(LOGON_INFO, server_info, &sam3);
     615        nt_status = auth_convert_user_info_dc_saminfo3(LOGON_INFO, user_info_dc, &sam3);
    624616        if (!NT_STATUS_IS_OK(nt_status)) {
    625617                DEBUG(1, ("Getting Samba info failed: %s\n", nt_errstr(nt_status)));
     
    631623        LOGON_INFO->info3 = *sam3;
    632624
    633         ret = krb5_unparse_name_flags(context, client_principal, 
     625        ret = krb5_unparse_name_flags(context, client_principal,
    634626                                      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
    635627        if (ret) {
     
    644636        unix_to_nt_time(&LOGON_NAME->logon_time, tgs_authtime);
    645637
    646         ret = kerberos_encode_pac(mem_ctx,
    647                                   iconv_convenience,
    648                                   pac_data,
     638        ret = kerberos_encode_pac(mem_ctx,
     639                                  pac_data,
    649640                                  context,
    650641                                  krbtgt_keyblock,
     
    655646}
    656647
    657 krb5_error_code kerberos_pac_to_server_info(TALLOC_CTX *mem_ctx,
    658                                                 struct smb_iconv_convenience *iconv_convenience,
    659                                                 krb5_pac pac,
    660                                                 krb5_context context,
    661                                                 struct auth_serversupplied_info **server_info)
     648krb5_error_code kerberos_pac_to_user_info_dc(TALLOC_CTX *mem_ctx,
     649                                             krb5_pac pac,
     650                                             krb5_context context,
     651                                             struct auth_user_info_dc **user_info_dc,
     652                                             struct PAC_SIGNATURE_DATA *pac_srv_sig,
     653                                             struct PAC_SIGNATURE_DATA *pac_kdc_sig)
    662654{
    663655        NTSTATUS nt_status;
     
    669661
    670662        union PAC_INFO info;
    671         union netr_Validation validation;
    672         struct auth_serversupplied_info *server_info_out;
     663        struct auth_user_info_dc *user_info_dc_out;
    673664
    674665        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     
    686677        pac_logon_info_in = data_blob_const(k5pac_logon_info_in.data, k5pac_logon_info_in.length);
    687678
    688         ndr_err = ndr_pull_union_blob(&pac_logon_info_in, tmp_ctx, iconv_convenience, &info,
     679        ndr_err = ndr_pull_union_blob(&pac_logon_info_in, tmp_ctx, &info,
    689680                                      PAC_TYPE_LOGON_INFO,
    690681                                      (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
     
    698689
    699690        /* Pull this right into the normal auth sysstem structures */
    700         validation.sam3 = &info.logon_info.info->info3;
    701         nt_status = make_server_info_netlogon_validation(mem_ctx,
    702                                                          "",
    703                                                          3, &validation,
    704                                                          &server_info_out);
     691        nt_status = make_user_info_dc_pac(mem_ctx,
     692                                         info.logon_info.info,
     693                                         &user_info_dc_out);
    705694        if (!NT_STATUS_IS_OK(nt_status)) {
    706695                talloc_free(tmp_ctx);
    707696                return EINVAL;
    708697        }
    709        
    710         ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_SRV_CHECKSUM, &k5pac_srv_checksum_in);
    711         if (ret != 0) {
    712                 talloc_free(tmp_ctx);
    713                 return ret;
    714         }
    715 
    716         pac_srv_checksum_in = data_blob_const(k5pac_srv_checksum_in.data, k5pac_srv_checksum_in.length);
    717                
    718         ndr_err = ndr_pull_struct_blob(&pac_srv_checksum_in, server_info_out,
    719                                        iconv_convenience, &server_info_out->pac_srv_sig,
    720                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    721         krb5_data_free(&k5pac_srv_checksum_in);
    722         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    723                 nt_status = ndr_map_error2ntstatus(ndr_err);
    724                 DEBUG(0,("can't parse the KDC signature: %s\n",
    725                         nt_errstr(nt_status)));
    726                 return EINVAL;
    727         }
    728 
    729         ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_KDC_CHECKSUM, &k5pac_kdc_checksum_in);
    730         if (ret != 0) {
    731                 talloc_free(tmp_ctx);
    732                 return ret;
    733         }
    734 
    735         pac_kdc_checksum_in = data_blob_const(k5pac_kdc_checksum_in.data, k5pac_kdc_checksum_in.length);
    736                
    737         ndr_err = ndr_pull_struct_blob(&pac_kdc_checksum_in, server_info_out,
    738                                        iconv_convenience, &server_info_out->pac_kdc_sig,
    739                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
    740         krb5_data_free(&k5pac_kdc_checksum_in);
    741         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    742                 nt_status = ndr_map_error2ntstatus(ndr_err);
    743                 DEBUG(0,("can't parse the KDC signature: %s\n",
    744                         nt_errstr(nt_status)));
    745                 return EINVAL;
    746         }
    747 
    748         *server_info = server_info_out;
    749        
     698
     699        if (pac_srv_sig) {
     700                ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_SRV_CHECKSUM, &k5pac_srv_checksum_in);
     701                if (ret != 0) {
     702                        talloc_free(tmp_ctx);
     703                        return ret;
     704                }
     705
     706                pac_srv_checksum_in = data_blob_const(k5pac_srv_checksum_in.data, k5pac_srv_checksum_in.length);
     707
     708                ndr_err = ndr_pull_struct_blob(&pac_srv_checksum_in, pac_srv_sig,
     709                                               pac_srv_sig,
     710                                               (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
     711                krb5_data_free(&k5pac_srv_checksum_in);
     712                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     713                        nt_status = ndr_map_error2ntstatus(ndr_err);
     714                        DEBUG(0,("can't parse the KDC signature: %s\n",
     715                                 nt_errstr(nt_status)));
     716                        return EINVAL;
     717                }
     718        }
     719
     720        if (pac_kdc_sig) {
     721                ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_KDC_CHECKSUM, &k5pac_kdc_checksum_in);
     722                if (ret != 0) {
     723                        talloc_free(tmp_ctx);
     724                        return ret;
     725                }
     726
     727                pac_kdc_checksum_in = data_blob_const(k5pac_kdc_checksum_in.data, k5pac_kdc_checksum_in.length);
     728
     729                ndr_err = ndr_pull_struct_blob(&pac_kdc_checksum_in, pac_kdc_sig,
     730                                               pac_kdc_sig,
     731                                               (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA);
     732                krb5_data_free(&k5pac_kdc_checksum_in);
     733                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     734                        nt_status = ndr_map_error2ntstatus(ndr_err);
     735                        DEBUG(0,("can't parse the KDC signature: %s\n",
     736                                 nt_errstr(nt_status)));
     737                        return EINVAL;
     738                }
     739        }
     740        *user_info_dc = user_info_dc_out;
     741
    750742        return 0;
    751743}
    752744
    753745
    754 NTSTATUS kerberos_pac_blob_to_server_info(TALLOC_CTX *mem_ctx,
    755                                                      struct smb_iconv_convenience *iconv_convenience,
    756                                                      DATA_BLOB pac_blob,
    757                                                      krb5_context context,
    758                                                      struct auth_serversupplied_info **server_info)
     746NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx,
     747                                           DATA_BLOB pac_blob,
     748                                           krb5_context context,
     749                                           struct auth_user_info_dc **user_info_dc,
     750                                           struct PAC_SIGNATURE_DATA *pac_srv_sig,
     751                                           struct PAC_SIGNATURE_DATA *pac_kdc_sig)
    759752{
    760753        krb5_error_code ret;
    761754        krb5_pac pac;
    762         ret = krb5_pac_parse(context, 
    763                              pac_blob.data, pac_blob.length, 
     755        ret = krb5_pac_parse(context,
     756                             pac_blob.data, pac_blob.length,
    764757                             &pac);
    765758        if (ret) {
     
    768761
    769762
    770         ret = kerberos_pac_to_server_info(mem_ctx, iconv_convenience, pac, context, server_info);
     763        ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig);
    771764        krb5_pac_free(context, pac);
    772765        if (ret) {
  • vendor/current/source4/auth/kerberos/kerberos_util.c

    r414 r740  
    2727#include "auth/credentials/credentials_proto.h"
    2828#include "auth/credentials/credentials_krb5.h"
     29#include "auth/kerberos/kerberos_credentials.h"
     30#include "auth/kerberos/kerberos_util.h"
     31#include <ldb.h>
     32#include "param/secrets.h"
    2933
    3034struct principal_container {
    3135        struct smb_krb5_context *smb_krb5_context;
    3236        krb5_principal principal;
     37        const char *string_form; /* Optional */
    3338};
    3439
     
    4146}
    4247
    43 static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
    44                                                        struct cli_credentials *machine_account,
    45                                                        struct smb_krb5_context *smb_krb5_context,
    46                                                        krb5_principal *salt_princ)
    47 {
     48
     49static krb5_error_code parse_principal(TALLOC_CTX *parent_ctx,
     50                                       const char *princ_string,
     51                                       struct smb_krb5_context *smb_krb5_context,
     52                                       krb5_principal *princ,
     53                                       const char **error_string)
     54{
     55        int ret;
     56        struct principal_container *mem_ctx;
     57        if (princ_string == NULL) {
     58                 *princ = NULL;
     59                 return 0;
     60        }
     61
     62        ret = krb5_parse_name(smb_krb5_context->krb5_context,
     63                              princ_string, princ);
     64
     65        if (ret) {
     66                (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
     67                return ret;
     68        }
     69
     70        mem_ctx = talloc(parent_ctx, struct principal_container);
     71        if (!mem_ctx) {
     72                (*error_string) = error_message(ENOMEM);
     73                return ENOMEM;
     74        }
     75
     76        /* This song-and-dance effectivly puts the principal
     77         * into talloc, so we can't loose it. */
     78        mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
     79        mem_ctx->principal = *princ;
     80        talloc_set_destructor(mem_ctx, free_principal);
     81        return 0;
     82}
     83
     84static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx,
     85                                           struct ldb_message *msg,
     86                                           struct smb_krb5_context *smb_krb5_context,
     87                                           struct principal_container ***principals_out,
     88                                           const char **error_string)
     89{
     90        unsigned int i;
    4891        krb5_error_code ret;
    49         char *machine_username;
    50         char *salt_body;
    51         char *lower_realm;
    52         const char *salt_principal;
    53         struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
    54         if (!mem_ctx) {
    55                 return ENOMEM;
    56         }
    57 
    58         salt_principal = cli_credentials_get_salt_principal(machine_account);
     92        char *upper_realm;
     93        const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
     94        const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
     95        struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
     96        TALLOC_CTX *tmp_ctx;
     97        struct principal_container **principals;
     98        tmp_ctx = talloc_new(parent_ctx);
     99        if (!tmp_ctx) {
     100                *error_string = "Cannot allocate tmp_ctx";
     101                return ENOMEM;
     102        }
     103
     104        if (!realm) {
     105                *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
     106                return EINVAL;
     107        }
     108
     109        upper_realm = strupper_talloc(tmp_ctx, realm);
     110        if (!upper_realm) {
     111                talloc_free(tmp_ctx);
     112                *error_string = "Cannot allocate full upper case realm";
     113                return ENOMEM;
     114        }
     115
     116        principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2);
     117
     118        spn_el = ldb_msg_find_element(msg, "servicePrincipalName");
     119        for (i=0; spn_el && i < spn_el->num_values; i++) {
     120                principals[i] = talloc(principals, struct principal_container);
     121                if (!principals[i]) {
     122                        talloc_free(tmp_ctx);
     123                        *error_string = "Cannot allocate mem_ctx";
     124                        return ENOMEM;
     125                }
     126
     127                principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
     128                principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s",
     129                                                             (int)spn_el->values[i].length,
     130                                                             (int)spn_el->values[i].length,
     131                                                             (const char *)spn_el->values[i].data, upper_realm);
     132                if (!principals[i]->string_form) {
     133                        talloc_free(tmp_ctx);
     134                        *error_string = "Cannot allocate full samAccountName";
     135                        return ENOMEM;
     136                }
     137
     138                ret = krb5_parse_name(smb_krb5_context->krb5_context,
     139                                      principals[i]->string_form, &principals[i]->principal);
     140               
     141                if (ret) {
     142                        talloc_free(tmp_ctx);
     143                        (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
     144                        return ret;
     145                }
     146
     147                /* This song-and-dance effectivly puts the principal
     148                 * into talloc, so we can't loose it. */
     149                talloc_set_destructor(principals[i], free_principal);
     150        }
     151
     152        if (samAccountName) {
     153                principals[i] = talloc(principals, struct principal_container);
     154                if (!principals[i]) {
     155                        talloc_free(tmp_ctx);
     156                        *error_string = "Cannot allocate mem_ctx";
     157                        return ENOMEM;
     158                }
     159
     160                principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context);
     161                principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm);
     162                if (!principals[i]->string_form) {
     163                        talloc_free(tmp_ctx);
     164                        *error_string = "Cannot allocate full samAccountName";
     165                        return ENOMEM;
     166                }
     167               
     168                ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName,
     169                                          NULL);
     170                if (ret) {
     171                        talloc_free(tmp_ctx);
     172                        (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
     173                        return ret;
     174                }
     175               
     176                /* This song-and-dance effectivly puts the principal
     177                 * into talloc, so we can't loose it. */
     178                talloc_set_destructor(principals[i], free_principal);
     179                i++;
     180        }
     181
     182        principals[i] = NULL;
     183        *principals_out = talloc_steal(parent_ctx, principals);
     184
     185        talloc_free(tmp_ctx);
     186        return ret;
     187}
     188
     189static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx,
     190                                               struct ldb_message *msg,
     191                                               struct smb_krb5_context *smb_krb5_context,
     192                                               krb5_principal *salt_princ,
     193                                               const char **error_string)
     194{
     195        const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL);
     196        const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
     197        const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL);
    59198        if (salt_principal) {
    60                 ret = krb5_parse_name(smb_krb5_context->krb5_context, salt_principal, salt_princ);
    61         } else {
    62                 machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account));
    63                
     199                return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string);
     200        } else if (samAccountName) {
     201                krb5_error_code ret;
     202                char *machine_username;
     203                char *salt_body;
     204                char *lower_realm;
     205                char *upper_realm;
     206
     207                TALLOC_CTX *tmp_ctx;
     208                struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
     209                if (!mem_ctx) {
     210                        *error_string = "Cannot allocate mem_ctx";
     211                        return ENOMEM;
     212                }
     213
     214                tmp_ctx = talloc_new(mem_ctx);
     215                if (!tmp_ctx) {
     216                        talloc_free(mem_ctx);
     217                        *error_string = "Cannot allocate tmp_ctx";
     218                        return ENOMEM;
     219                }
     220
     221                if (!realm) {
     222                        *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm";
     223                        return EINVAL;
     224                }
     225               
     226                machine_username = talloc_strdup(tmp_ctx, samAccountName);
    64227                if (!machine_username) {
    65228                        talloc_free(mem_ctx);
     229                        *error_string = "Cannot duplicate samAccountName";
    66230                        return ENOMEM;
    67231                }
     
    70234                        machine_username[strlen(machine_username)-1] = '\0';
    71235                }
    72                 lower_realm = strlower_talloc(mem_ctx, cli_credentials_get_realm(machine_account));
     236
     237                lower_realm = strlower_talloc(tmp_ctx, realm);
    73238                if (!lower_realm) {
    74239                        talloc_free(mem_ctx);
     240                        *error_string = "Cannot allocate to lower case realm";
    75241                        return ENOMEM;
    76242                }
    77243               
    78                 salt_body = talloc_asprintf(mem_ctx, "%s.%s", machine_username,
     244                upper_realm = strupper_talloc(tmp_ctx, realm);
     245                if (!upper_realm) {
     246                        talloc_free(mem_ctx);
     247                        *error_string = "Cannot allocate to upper case realm";
     248                        return ENOMEM;
     249                }
     250               
     251                salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username,
    79252                                            lower_realm);
     253                talloc_free(lower_realm);
     254                talloc_free(machine_username);
    80255                if (!salt_body) {
    81256                        talloc_free(mem_ctx);
    82                 return ENOMEM;
     257                        *error_string = "Cannot form salt principal body";
     258                        return ENOMEM;
    83259                }
    84260               
    85261                ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ,
    86                                           cli_credentials_get_realm(machine_account),
     262                                          upper_realm,
    87263                                          "host", salt_body, NULL);
    88         }
    89 
    90         if (ret == 0) {
    91                 /* This song-and-dance effectivly puts the principal
    92                  * into talloc, so we can't loose it. */
    93                 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
    94                 mem_ctx->principal = *salt_princ;
    95                 talloc_set_destructor(mem_ctx, free_principal);
    96         }
    97         return ret;
     264                if (ret == 0) {
     265                        /* This song-and-dance effectivly puts the principal
     266                         * into talloc, so we can't loose it. */
     267                        mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
     268                        mem_ctx->principal = *salt_princ;
     269                        talloc_set_destructor(mem_ctx, free_principal);
     270                } else {
     271                        (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx);
     272                }
     273                talloc_free(tmp_ctx);
     274                return ret;
     275        } else {
     276                (*error_string) = "Cannot determine salt principal, no saltPrincipal or samAccountName specified";
     277                return EINVAL;
     278        }
    98279}
    99280
     
    103284 * system by means of a destructor (do *not* free). */
    104285
    105  krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
     286krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,
    106287                                            struct cli_credentials *credentials,
    107288                                            struct smb_krb5_context *smb_krb5_context,
    108                                             krb5_principal *princ)
     289                                            krb5_principal *princ,
     290                                            enum credentials_obtained *obtained,
     291                                            const char **error_string)
    109292{
    110293        krb5_error_code ret;
    111294        const char *princ_string;
    112         struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);
     295        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    113296        if (!mem_ctx) {
    114                 return ENOMEM;
    115         }
    116        
    117         princ_string = cli_credentials_get_principal(credentials, mem_ctx);
    118 
    119         /* A NULL here has meaning, as the gssapi server case will
    120          * then use the principal from the client */
     297                (*error_string) = error_message(ENOMEM);
     298                return ENOMEM;
     299        }
     300        princ_string = cli_credentials_get_principal_and_obtained(credentials, mem_ctx, obtained);
    121301        if (!princ_string) {
    122                 talloc_free(mem_ctx);
    123                 princ = NULL;
    124                 return 0;
    125         }
    126 
    127         ret = krb5_parse_name(smb_krb5_context->krb5_context,
    128                               princ_string, princ);
    129 
    130         if (ret == 0) {
    131                 /* This song-and-dance effectivly puts the principal
    132                  * into talloc, so we can't loose it. */
    133                 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
    134                 mem_ctx->principal = *princ;
    135                 talloc_set_destructor(mem_ctx, free_principal);
    136         }
     302                (*error_string) = error_message(ENOMEM);
     303                return ENOMEM;
     304        }
     305
     306        ret = parse_principal(parent_ctx, princ_string,
     307                              smb_krb5_context, princ, error_string);
     308        talloc_free(mem_ctx);
    137309        return ret;
     310}
     311
     312/* Obtain the principal set on this context.  Requires a
     313 * smb_krb5_context because we are doing krb5 principal parsing with
     314 * the library routines.  The returned princ is placed in the talloc
     315 * system by means of a destructor (do *not* free). */
     316
     317 krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx,
     318                                                        struct cli_credentials *credentials,
     319                                                        struct smb_krb5_context *smb_krb5_context,
     320                                                        krb5_principal *princ,
     321                                                        const char **error_string)
     322{
     323        return parse_principal(parent_ctx, cli_credentials_get_impersonate_principal(credentials),
     324                               smb_krb5_context, princ, error_string);
    138325}
    139326
     
    146333                                 struct cli_credentials *credentials,
    147334                                 struct smb_krb5_context *smb_krb5_context,
    148                                  krb5_ccache ccache)
     335                                 struct tevent_context *event_ctx,
     336                                 krb5_ccache ccache,
     337                                 enum credentials_obtained *obtained,
     338                                 const char **error_string)
    149339{
    150340        krb5_error_code ret;
    151         const char *password;
     341        const char *password, *target_service;
    152342        time_t kdc_time = 0;
    153343        krb5_principal princ;
     344        krb5_principal impersonate_principal;
    154345        int tries;
    155346        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     347        krb5_get_init_creds_opt *krb_options;
    156348
    157349        if (!mem_ctx) {
    158                 return ENOMEM;
    159         }
    160 
    161         ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ);
     350                (*error_string) = strerror(ENOMEM);
     351                return ENOMEM;
     352        }
     353
     354        ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ, obtained, error_string);
    162355        if (ret) {
    163356                talloc_free(mem_ctx);
     
    165358        }
    166359
     360        ret = impersonate_principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &impersonate_principal, error_string);
     361        if (ret) {
     362                talloc_free(mem_ctx);
     363                return ret;
     364        }
     365
     366        target_service = cli_credentials_get_target_service(credentials);
     367
    167368        password = cli_credentials_get_password(credentials);
     369
     370        /* setup the krb5 options we want */
     371        if ((ret = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context, &krb_options))) {
     372                (*error_string) = talloc_asprintf(credentials, "krb5_get_init_creds_opt_alloc failed (%s)\n",
     373                                                  smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     374                                                                             ret, mem_ctx));
     375                talloc_free(mem_ctx);
     376                return ret;
     377        }
     378
     379        /* get the defaults */
     380        krb5_get_init_creds_opt_set_default_flags(smb_krb5_context->krb5_context, NULL, NULL, krb_options);
     381
     382        /* set if we want a forwardable ticket */
     383        switch (cli_credentials_get_krb_forwardable(credentials)) {
     384        case CRED_AUTO_KRB_FORWARDABLE:
     385                break;
     386        case CRED_NO_KRB_FORWARDABLE:
     387                krb5_get_init_creds_opt_set_forwardable(krb_options, FALSE);
     388                break;
     389        case CRED_FORCE_KRB_FORWARDABLE:
     390                krb5_get_init_creds_opt_set_forwardable(krb_options, TRUE);
     391                break;
     392        }
    168393
    169394        tries = 2;
    170395        while (tries--) {
     396                struct tevent_context *previous_ev;
     397                /* Do this every time, in case we have weird recursive issues here */
     398                ret = smb_krb5_context_set_event_ctx(smb_krb5_context, event_ctx, &previous_ev);
     399                if (ret) {
     400                        talloc_free(mem_ctx);
     401                        return ret;
     402                }
    171403                if (password) {
    172404                        ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache,
    173                                                          princ,
    174                                                          password, NULL, &kdc_time);
     405                                                         princ, password,
     406                                                         impersonate_principal, target_service,
     407                                                         krb_options,
     408                                                         NULL, &kdc_time);
     409                } else if (impersonate_principal) {
     410                        talloc_free(mem_ctx);
     411                        (*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock.  A password must be specified in the credentials";
     412                        return EINVAL;
    175413                } else {
    176414                        /* No password available, try to use a keyblock instead */
     
    181419                        if (!mach_pwd) {
    182420                                talloc_free(mem_ctx);
    183                                 DEBUG(1, ("kinit_to_ccache: No password available for kinit\n"));
     421                                (*error_string) = "kinit_to_ccache: No password available for kinit\n";
     422                                krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
     423                                smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
    184424                                return EINVAL;
    185425                        }
     
    191431                        if (ret == 0) {
    192432                                ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, ccache,
    193                                                                  princ,
    194                                                                  &keyblock, NULL, &kdc_time);
     433                                                                 princ, &keyblock,
     434                                                                 target_service, krb_options,
     435                                                                 NULL, &kdc_time);
    195436                                krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &keyblock);
    196437                        }
    197438                }
     439
     440                smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx);
    198441
    199442                if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
     
    207450        }
    208451
     452        krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options);
     453
    209454        if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
    210                 DEBUG(1,("kinit for %s failed (%s)\n",
    211                          cli_credentials_get_principal(credentials, mem_ctx),
    212                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    213                                                     ret, mem_ctx)));
     455                (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n",
     456                                                  cli_credentials_get_principal(credentials, mem_ctx),
     457                                                  smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     458                                                                             ret, mem_ctx));
    214459                talloc_free(mem_ctx);
    215460                return ret;
     
    228473                                      credentials,
    229474                                      smb_krb5_context,
    230                                       ccache);
    231         }
     475                                      event_ctx,
     476                                      ccache, obtained,
     477                                      error_string);
     478        }
     479
    232480        if (ret) {
    233                 DEBUG(1,("kinit for %s failed (%s)\n",
    234                          cli_credentials_get_principal(credentials, mem_ctx),
    235                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    236                                                     ret, mem_ctx)));
     481                (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n",
     482                                                  cli_credentials_get_principal(credentials, mem_ctx),
     483                                                  smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     484                                                                             ret, mem_ctx));
    237485                talloc_free(mem_ctx);
    238486                return ret;
     
    274522
    275523static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx,
    276                                        const char *princ_string,
    277                                        krb5_principal princ,
     524                                       struct principal_container **principals,
    278525                                       krb5_principal salt_princ,
    279526                                       int kvno,
    280527                                       const char *password_s,
    281528                                       struct smb_krb5_context *smb_krb5_context,
    282                                        const char **enctype_strings,
    283                                        krb5_keytab keytab)
    284 {
    285         int i;
     529                                       krb5_enctype *enctypes,
     530                                       krb5_keytab keytab,
     531                                       const char **error_string)
     532{
     533        unsigned int i, p;
    286534        krb5_error_code ret;
    287535        krb5_data password;
    288         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    289         if (!mem_ctx) {
    290                 return ENOMEM;
    291         }
    292536
    293537        password.data = discard_const_p(char *, password_s);
    294538        password.length = strlen(password_s);
    295539
    296         for (i=0; enctype_strings[i]; i++) {
     540        for (i=0; enctypes[i]; i++) {
    297541                krb5_keytab_entry entry;
    298                 krb5_enctype enctype;
    299                 ret = krb5_string_to_enctype(smb_krb5_context->krb5_context, enctype_strings[i], &enctype);
     542
     543                ZERO_STRUCT(entry);
     544
     545                ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context,
     546                                                      salt_princ, &password, &entry.keyblock, enctypes[i]);
    300547                if (ret != 0) {
    301                         DEBUG(1, ("Failed to interpret %s as a krb5 encryption type: %s\n",                               
    302                                   enctype_strings[i],
    303                                   smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    304                                                              ret, mem_ctx)));
    305                         talloc_free(mem_ctx);
    306548                        return ret;
    307549                }
    308                 ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context,
    309                                                       salt_princ, &password, &entry.keyblock, enctype);
    310                 if (ret != 0) {
    311                         talloc_free(mem_ctx);
    312                         return ret;
    313                 }
    314 
    315                 entry.principal = princ;
    316                 entry.vno       = kvno;
    317                 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);
    318                 if (ret != 0) {
    319                         DEBUG(1, ("Failed to add %s entry for %s(kvno %d) to keytab: %s\n",
    320                                   enctype_strings[i],
    321                                   princ_string,
    322                                   kvno,
    323                                   smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    324                                                              ret, mem_ctx)));
    325                         talloc_free(mem_ctx);
    326                         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    327                         return ret;
    328                 }
    329 
    330                 DEBUG(5, ("Added %s(kvno %d) to keytab (%s)\n",
    331                           princ_string, kvno,
    332                           enctype_strings[i]));
    333                
     550
     551                entry.vno = kvno;
     552
     553                for (p=0; principals[p]; p++) {
     554                        entry.principal = principals[p]->principal;
     555                        ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);
     556                        if (ret != 0) {
     557                                char *k5_error_string = smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     558                                                                                   ret, NULL);
     559                                *error_string = talloc_asprintf(parent_ctx, "Failed to add enctype %d entry for %s(kvno %d) to keytab: %s\n",
     560                                                                (int)enctypes[i],
     561                                                                principals[p]->string_form,
     562                                                                kvno,
     563                                                                k5_error_string);
     564                                talloc_free(k5_error_string);
     565                                krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
     566                                return ret;
     567                        }
     568
     569                        DEBUG(5, ("Added %s(kvno %d) to keytab (enctype %d)\n",
     570                                  principals[p]->string_form, kvno,
     571                                  (int)enctypes[i]));
     572                }
    334573                krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    335574        }
    336         talloc_free(mem_ctx);
    337575        return 0;
    338576}
    339577
    340578static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx,
    341                          struct cli_credentials *machine_account,
    342                          struct smb_krb5_context *smb_krb5_context,
    343                          const char **enctype_strings,
    344                          krb5_keytab keytab,
    345                          bool add_old)
     579                                     struct ldb_message *msg,
     580                                     struct principal_container **principals,
     581                                     struct smb_krb5_context *smb_krb5_context,
     582                                     krb5_keytab keytab,
     583                                     bool add_old,
     584                                     const char **error_string)
    346585{
    347586        krb5_error_code ret;
     
    349588        const char *old_secret;
    350589        int kvno;
     590        uint32_t enctype_bitmap;
    351591        krb5_principal salt_princ;
    352         krb5_principal princ;
    353         const char *princ_string;
    354 
     592        krb5_enctype *enctypes;
    355593        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    356594        if (!mem_ctx) {
    357                 return ENOMEM;
    358         }
    359 
    360         princ_string = cli_credentials_get_principal(machine_account, mem_ctx);
    361         /* Get the principal we will store the new keytab entries under */
    362         ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ);
     595                *error_string = "unable to allocate tmp_ctx for create_keytab";
     596                return ENOMEM;
     597        }
     598
     599        /* The salt used to generate these entries may be different however, fetch that */
     600        ret = salt_principal_from_msg(mem_ctx, msg,
     601                                      smb_krb5_context,
     602                                      &salt_princ, error_string);
    363603        if (ret) {
    364                 DEBUG(1,("create_keytab: makeing krb5 principal failed (%s)\n",
    365                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    366                                                     ret, mem_ctx)));
    367                 talloc_free(mem_ctx);
    368                 return ret;
    369         }
    370 
    371         /* The salt used to generate these entries may be different however, fetch that */
    372         ret = salt_principal_from_credentials(mem_ctx, machine_account,
    373                                               smb_krb5_context,
    374                                               &salt_princ);
     604                talloc_free(mem_ctx);
     605                return ret;
     606        }
     607
     608        kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);
     609
     610        /* Finally, do the dance to get the password to put in the entry */
     611        password_s =  ldb_msg_find_attr_as_string(msg, "secret", NULL);
     612
     613        if (!password_s) {
     614                /* There is no password here, so nothing to do */
     615                talloc_free(mem_ctx);
     616                return 0;
     617        }
     618
     619        if (add_old && kvno != 0) {
     620                old_secret = ldb_msg_find_attr_as_string(msg, "priorSecret", NULL);
     621        } else {
     622                old_secret = NULL;
     623        }
     624
     625        enctype_bitmap = (uint32_t)ldb_msg_find_attr_as_int(msg, "msDS-SupportedEncryptionTypes", ENC_ALL_TYPES);
     626       
     627        ret = kerberos_enctype_bitmap_to_enctypes(mem_ctx, enctype_bitmap, &enctypes);
    375628        if (ret) {
    376                 DEBUG(1,("create_keytab: makeing salt principal failed (%s)\n",
    377                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    378                                                     ret, mem_ctx)));
    379                 talloc_free(mem_ctx);
    380                 return ret;
    381         }
    382 
    383         /* Finally, do the dance to get the password to put in the entry */
    384         password_s = cli_credentials_get_password(machine_account);
    385         if (!password_s) {
    386                 krb5_keytab_entry entry;
    387                 const struct samr_Password *mach_pwd;
    388 
    389                 if (!str_list_check(enctype_strings, "arcfour-hmac-md5")) {
    390                         DEBUG(1, ("Asked to create keytab, but with only an NT hash supplied, "
    391                                   "but not listing arcfour-hmac-md5 as an enc type to include in the keytab!\n"));
    392                         talloc_free(mem_ctx);
    393                         return EINVAL;
    394                 }
    395 
    396                 /* If we don't have the plaintext password, try for
    397                  * the MD4 password hash */
    398                 mach_pwd = cli_credentials_get_nt_hash(machine_account, mem_ctx);
    399                 if (!mach_pwd) {
    400                         /* OK, nothing to do here */
    401                         talloc_free(mem_ctx);
    402                         return 0;
    403                 }
    404                 ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
    405                                          ETYPE_ARCFOUR_HMAC_MD5,
    406                                          mach_pwd->hash, sizeof(mach_pwd->hash),
    407                                          &entry.keyblock);
     629                *error_string = talloc_asprintf(parent_ctx, "create_keytab: generating list of encryption types failed (%s)\n",
     630                                                smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     631                                                                           ret, mem_ctx));
     632                talloc_free(mem_ctx);
     633                return ret;
     634        }
     635
     636        ret = keytab_add_keys(mem_ctx, principals,
     637                              salt_princ,
     638                              kvno, password_s, smb_krb5_context,
     639                              enctypes, keytab, error_string);
     640        if (ret) {
     641                talloc_free(mem_ctx);
     642                return ret;
     643        }
     644       
     645        if (old_secret) {
     646                ret = keytab_add_keys(mem_ctx, principals,
     647                                      salt_princ,
     648                                      kvno - 1, old_secret, smb_krb5_context,
     649                                      enctypes, keytab, error_string);
    408650                if (ret) {
    409                         DEBUG(1, ("create_keytab: krb5_keyblock_init failed: %s\n",
    410                                   smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    411                                                              ret, mem_ctx)));
    412651                        talloc_free(mem_ctx);
    413652                        return ret;
    414653                }
    415 
    416                 entry.principal = princ;
    417                 entry.vno       = cli_credentials_get_kvno(machine_account);
    418                 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);
    419                 if (ret) {
    420                         DEBUG(1, ("Failed to add ARCFOUR_HMAC (only) entry for %s to keytab: %s",
    421                                   cli_credentials_get_principal(machine_account, mem_ctx),
    422                                   smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    423                                                              ret, mem_ctx)));
    424                         talloc_free(mem_ctx);
    425                         krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    426                         return ret;
    427                 }
    428                
    429                 DEBUG(5, ("Added %s(kvno %d) to keytab (arcfour-hmac-md5)\n",
    430                           cli_credentials_get_principal(machine_account, mem_ctx),
    431                           cli_credentials_get_kvno(machine_account)));
    432 
    433                 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);
    434 
    435                 /* Can't go any further, we only have this one key */
    436                 talloc_free(mem_ctx);
    437                 return 0;
    438         }
    439        
    440         kvno = cli_credentials_get_kvno(machine_account);
    441         /* good, we actually have the real plaintext */
    442         ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ,
    443                               kvno, password_s, smb_krb5_context,
    444                               enctype_strings, keytab);
    445         if (!ret) {
    446                 talloc_free(mem_ctx);
    447                 return ret;
    448         }
    449 
    450         if (!add_old || kvno == 0) {
    451                 talloc_free(mem_ctx);
    452                 return 0;
    453         }
    454 
    455         old_secret = cli_credentials_get_old_password(machine_account);
    456         if (!old_secret) {
    457                 talloc_free(mem_ctx);
    458                 return 0;
    459         }
    460        
    461         ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ,
    462                               kvno - 1, old_secret, smb_krb5_context,
    463                               enctype_strings, keytab);
    464         if (!ret) {
    465                 talloc_free(mem_ctx);
    466                 return ret;
    467654        }
    468655
    469656        talloc_free(mem_ctx);
    470         return 0;
    471 }
    472 
     657        return ret;
     658}
    473659
    474660/*
     
    482668
    483669static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
    484                                           struct cli_credentials *machine_account,
     670                                          struct ldb_message *msg,
     671                                          struct principal_container **principals,
     672                                          bool delete_all_kvno,
    485673                                          struct smb_krb5_context *smb_krb5_context,
    486                                           krb5_keytab keytab, bool *found_previous)
     674                                          krb5_keytab keytab, bool *found_previous,
     675                                          const char **error_string)
    487676{
    488677        krb5_error_code ret, ret2;
    489678        krb5_kt_cursor cursor;
    490         krb5_principal princ;
    491679        int kvno;
    492680        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    493         const char *princ_string;
     681
    494682        if (!mem_ctx) {
    495683                return ENOMEM;
     
    497685
    498686        *found_previous = false;
    499         princ_string = cli_credentials_get_principal(machine_account, mem_ctx);
    500 
    501         /* Get the principal we will store the new keytab entries under */
    502         ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ);
    503         if (ret) {
    504                 DEBUG(1,("update_keytab: makeing krb5 principal failed (%s)\n",
    505                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    506                                                     ret, mem_ctx)));
    507                 talloc_free(mem_ctx);
    508                 return ret;
    509         }
    510 
    511         kvno = cli_credentials_get_kvno(machine_account);
     687
     688        kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0);
    512689
    513690        /* for each entry in the keytab */
     
    523700                return 0;
    524701        default:
    525                 DEBUG(1,("failed to open keytab for read of old entries: %s\n",
    526                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    527                                                     ret, mem_ctx)));
     702                *error_string = talloc_asprintf(parent_ctx, "failed to open keytab for read of old entries: %s\n",
     703                                                smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     704                                                                           ret, mem_ctx));
    528705                talloc_free(mem_ctx);
    529706                return ret;
     
    531708
    532709        while (!ret) {
     710                unsigned int i;
     711                bool matched = false;
    533712                krb5_keytab_entry entry;
    534713                ret = krb5_kt_next_entry(smb_krb5_context->krb5_context, keytab, &entry, &cursor);
     
    536715                        break;
    537716                }
    538                 /* if it matches our principal */
    539                 if (!krb5_kt_compare(smb_krb5_context->krb5_context, &entry, princ, 0, 0)) {
     717                for (i = 0; principals[i]; i++) {
     718                        /* if it matches our principal */
     719                        if (krb5_kt_compare(smb_krb5_context->krb5_context, &entry, principals[i]->principal, 0, 0)) {
     720                                matched = true;
     721                                break;
     722                        }
     723                }
     724
     725                if (!matched) {
    540726                        /* Free the entry, it wasn't the one we were looking for anyway */
    541727                        krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry);
     
    593779                break;
    594780        default:
    595                 DEBUG(1,("failed in deleting old entries for principal: %s: %s\n",
    596                          princ_string,
    597                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    598                                                     ret, mem_ctx)));
     781                *error_string = talloc_asprintf(parent_ctx, "failed in deleting old entries for principal: %s\n",
     782                                                smb_get_krb5_error_message(smb_krb5_context->krb5_context,
     783                                                                           ret, mem_ctx));
    599784        }
    600785        talloc_free(mem_ctx);
     
    603788
    604789krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
    605                            struct cli_credentials *machine_account,
    606                            struct smb_krb5_context *smb_krb5_context,
    607                            const char **enctype_strings,
    608                            struct keytab_container *keytab_container)
     790                                       struct smb_krb5_context *smb_krb5_context,
     791                                       struct ldb_context *ldb,
     792                                       struct ldb_message *msg,
     793                                       bool delete_all_kvno,
     794                                       const char **error_string)
    609795{
    610796        krb5_error_code ret;
    611797        bool found_previous;
    612         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     798        TALLOC_CTX *mem_ctx = talloc_new(NULL);
     799        struct keytab_container *keytab_container;
     800        struct principal_container **principals;
     801        const char *keytab_name;
     802
    613803        if (!mem_ctx) {
    614804                return ENOMEM;
    615805        }
    616806
    617         ret = remove_old_entries(mem_ctx, machine_account,
    618                                  smb_krb5_context, keytab_container->keytab, &found_previous);
     807        keytab_name = keytab_name_from_msg(mem_ctx, ldb, msg);
     808        if (!keytab_name) {
     809                return ENOENT;
     810        }
     811
     812        ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, &keytab_container);
     813
    619814        if (ret != 0) {
    620815                talloc_free(mem_ctx);
    621816                return ret;
    622817        }
     818
     819        DEBUG(5, ("Opened keytab %s\n", keytab_name));
     820
     821        /* Get the principal we will store the new keytab entries under */
     822        ret = principals_from_msg(mem_ctx, msg, smb_krb5_context, &principals, error_string);
     823
     824        if (ret != 0) {
     825                *error_string = talloc_asprintf(parent_ctx, "Failed to load principals from ldb message: %s\n", *error_string);
     826                talloc_free(mem_ctx);
     827                return ret;
     828        }
     829
     830        ret = remove_old_entries(mem_ctx, msg, principals, delete_all_kvno,
     831                                 smb_krb5_context, keytab_container->keytab, &found_previous, error_string);
     832        if (ret != 0) {
     833                *error_string = talloc_asprintf(parent_ctx, "Failed to remove old principals from keytab: %s\n", *error_string);
     834                talloc_free(mem_ctx);
     835                return ret;
     836        }
    623837       
    624         /* Create a new keytab.  If during the cleanout we found
    625          * entires for kvno -1, then don't try and duplicate them.
    626          * Otherwise, add kvno, and kvno -1 */
    627        
    628         ret = create_keytab(mem_ctx, machine_account, smb_krb5_context,
    629                             enctype_strings,
    630                             keytab_container->keytab,
    631                             found_previous ? false : true);
     838        if (!delete_all_kvno) {
     839                /* Create a new keytab.  If during the cleanout we found
     840                 * entires for kvno -1, then don't try and duplicate them.
     841                 * Otherwise, add kvno, and kvno -1 */
     842               
     843                ret = create_keytab(mem_ctx, msg, principals,
     844                                    smb_krb5_context,
     845                                    keytab_container->keytab,
     846                                    found_previous ? false : true, error_string);
     847        }
    632848        talloc_free(mem_ctx);
    633849        return ret;
     
    637853                                           struct cli_credentials *machine_account,
    638854                                           struct smb_krb5_context *smb_krb5_context,
    639                                            const char **enctype_strings,
    640855                                           struct keytab_container **keytab_container)
    641856{
     
    644859        const char *rand_string;
    645860        const char *keytab_name;
     861        struct ldb_message *msg;
     862        const char *error_string;
    646863        if (!mem_ctx) {
    647864                return ENOMEM;
     
    668885        }
    669886
    670         ret = smb_krb5_update_keytab(mem_ctx, machine_account, smb_krb5_context, enctype_strings, *keytab_container);
     887        msg = ldb_msg_new(mem_ctx);
     888        if (!msg) {
     889                talloc_free(mem_ctx);
     890                return ENOMEM;
     891        }
     892        ldb_msg_add_string(msg, "krb5Keytab", keytab_name);
     893        ldb_msg_add_string(msg, "secret", cli_credentials_get_password(machine_account));
     894        ldb_msg_add_string(msg, "samAccountName", cli_credentials_get_username(machine_account));
     895        ldb_msg_add_string(msg, "realm", cli_credentials_get_realm(machine_account));
     896        ldb_msg_add_fmt(msg, "msDS-KeyVersionNumber", "%d", (int)cli_credentials_get_kvno(machine_account));
     897
     898        ret = smb_krb5_update_keytab(mem_ctx, smb_krb5_context, NULL, msg, false, &error_string);
    671899        if (ret == 0) {
    672900                talloc_steal(parent_ctx, *keytab_container);
    673901        } else {
     902                DEBUG(0, ("Failed to create in-memory keytab: %s\n", error_string));
    674903                *keytab_container = NULL;
    675904        }
     
    677906        return ret;
    678907}
    679 
     908/* Translate between the IETF encryption type values and the Microsoft msDS-SupportedEncryptionTypes values */
     909uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum)
     910{
     911        switch (enc_type_enum) {
     912        case ENCTYPE_DES_CBC_CRC:
     913                return ENC_CRC32;
     914        case ENCTYPE_DES_CBC_MD5:
     915                return ENC_RSA_MD5;
     916        case ENCTYPE_ARCFOUR_HMAC_MD5:
     917                return ENC_RC4_HMAC_MD5;
     918        case ENCTYPE_AES128_CTS_HMAC_SHA1_96:
     919                return ENC_HMAC_SHA1_96_AES128;
     920        case ENCTYPE_AES256_CTS_HMAC_SHA1_96:
     921                return ENC_HMAC_SHA1_96_AES256;
     922        default:
     923                return 0;
     924        }
     925}
     926
     927/* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */
     928krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap)
     929{
     930        switch (enctype_bitmap) {
     931        case ENC_CRC32:
     932                return ENCTYPE_DES_CBC_CRC;
     933        case ENC_RSA_MD5:
     934                return ENCTYPE_DES_CBC_MD5;
     935        case ENC_RC4_HMAC_MD5:
     936                return ENCTYPE_ARCFOUR_HMAC_MD5;
     937        case ENC_HMAC_SHA1_96_AES128:
     938                return ENCTYPE_AES128_CTS_HMAC_SHA1_96;
     939        case ENC_HMAC_SHA1_96_AES256:
     940                return ENCTYPE_AES256_CTS_HMAC_SHA1_96;
     941        default:
     942                return 0;
     943        }
     944}
     945
     946/* Return an array of krb5_enctype values */
     947krb5_error_code kerberos_enctype_bitmap_to_enctypes(TALLOC_CTX *mem_ctx, uint32_t enctype_bitmap, krb5_enctype **enctypes)
     948{
     949        unsigned int i, j = 0;
     950        *enctypes = talloc_zero_array(mem_ctx, krb5_enctype, (8*sizeof(enctype_bitmap))+1);
     951        if (!*enctypes) {
     952                return ENOMEM;
     953        }
     954        for (i=0; i<(8*sizeof(enctype_bitmap)); i++) {
     955                uint32_t bit_value = (1 << i) & enctype_bitmap;
     956                if (bit_value & enctype_bitmap) {
     957                        (*enctypes)[j] = kerberos_enctype_bitmap_to_enctype(bit_value);
     958                        if (!(*enctypes)[j]) {
     959                                continue;
     960                        }
     961                        j++;
     962                }
     963        }
     964        (*enctypes)[j] = 0;
     965        return 0;
     966}
  • vendor/current/source4/auth/kerberos/krb5_init_context.c

    r414 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   Wrapper for krb5_init_context
     
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    3030#include "param/param.h"
    3131#include "libcli/resolve/resolve.h"
     32#include "../lib/tsocket/tsocket.h"
    3233
    3334/*
     
    4243        NTSTATUS status;
    4344        DATA_BLOB request, reply;
    44        
     45
    4546        struct packet_context *packet;
    4647
     
    5051};
    5152
    52 static krb5_error_code smb_krb5_context_destroy_1(struct smb_krb5_context *ctx)
    53 {
    54         krb5_free_context(ctx->krb5_context);
    55         return 0;
    56 }
    57 
    58 static krb5_error_code smb_krb5_context_destroy_2(struct smb_krb5_context *ctx)
     53static krb5_error_code smb_krb5_context_destroy(struct smb_krb5_context *ctx)
    5954{
    6055        /* Otherwise krb5_free_context will try and close what we have already free()ed */
    6156        krb5_set_warn_dest(ctx->krb5_context, NULL);
    6257        krb5_closelog(ctx->krb5_context, ctx->logf);
    63         smb_krb5_context_destroy_1(ctx);
     58        krb5_free_context(ctx->krb5_context);
    6459        return 0;
    6560}
     
    7267static void smb_krb5_debug_wrapper(const char *timestr, const char *msg, void *private_data)
    7368{
    74         DEBUG(2, ("Kerberos: %s\n", msg));
     69        DEBUG(3, ("Kerberos: %s\n", msg));
    7570}
    7671
     
    8984                return;
    9085        }
    91        
     86
    9287        blob = data_blob_talloc(tmp_ctx, NULL, dsize);
    9388        if (blob.data == NULL && dsize != 0) {
     
    9691                return;
    9792        }
    98        
     93
    9994        smb_krb5->status = socket_recv(smb_krb5->sock, blob.data, blob.length, &nread);
    10095        if (!NT_STATUS_IS_OK(smb_krb5->status)) {
     
    10398        }
    10499        blob.length = nread;
    105        
     100
    106101        if (nread == 0) {
    107102                smb_krb5->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
     
    109104                return;
    110105        }
    111        
    112         DEBUG(2,("Received smb_krb5 packet of length %d\n", 
     106
     107        DEBUG(2,("Received smb_krb5 packet of length %d\n",
    113108                 (int)blob.length));
    114        
     109
    115110        talloc_steal(smb_krb5, blob.data);
    116111        smb_krb5->reply = blob;
     
    131126  handle request timeouts
    132127*/
    133 static void smb_krb5_request_timeout(struct tevent_context *event_ctx, 
     128static void smb_krb5_request_timeout(struct tevent_context *event_ctx,
    134129                                  struct tevent_timer *te, struct timeval t,
    135130                                  void *private_data)
     
    154149
    155150        size_t len;
    156        
     151
    157152        len = smb_krb5->request.length;
    158153        status = socket_send(smb_krb5->sock, &smb_krb5->request, &len);
    159154
    160155        if (!NT_STATUS_IS_OK(status)) return;
    161        
     156
    162157        TEVENT_FD_READABLE(smb_krb5->fde);
    163158
     
    213208        krb5_error_code ret;
    214209        NTSTATUS status;
    215         struct socket_address *remote_addr;
    216210        const char *name;
    217211        struct addrinfo *ai, *a;
    218212        struct smb_krb5_socket *smb_krb5;
    219213
    220         struct tevent_context *ev = talloc_get_type(data, struct tevent_context);
    221 
    222         DATA_BLOB send_blob = data_blob_const(send_buf->data, send_buf->length);
     214        DATA_BLOB send_blob;
     215
     216        struct tevent_context *ev;
     217        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     218        if (!tmp_ctx) {
     219                return ENOMEM;
     220        }
     221
     222        if (!data) {
     223                /* If no event context was available, then create one for this loop */
     224                ev = tevent_context_init(tmp_ctx);
     225                if (!ev) {
     226                        talloc_free(tmp_ctx);
     227                        return ENOMEM;
     228                }
     229        } else {
     230                ev = talloc_get_type_abort(data, struct tevent_context);
     231        }
     232
     233        send_blob = data_blob_const(send_buf->data, send_buf->length);
    223234
    224235        ret = krb5_krbhst_get_addrinfo(context, hi, &ai);
    225236        if (ret) {
    226                 return ret;
    227         }
    228 
    229         for (a = ai; a; a = ai->ai_next) {
    230                 smb_krb5 = talloc(NULL, struct smb_krb5_socket);
     237                talloc_free(tmp_ctx);
     238                return ret;
     239        }
     240
     241        for (a = ai; a; a = a->ai_next) {
     242                struct socket_address *remote_addr;
     243                smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket);
    231244                if (!smb_krb5) {
     245                        talloc_free(tmp_ctx);
    232246                        return ENOMEM;
    233247                }
    234248                smb_krb5->hi = hi;
    235                
     249
    236250                switch (a->ai_family) {
    237251                case PF_INET:
     
    244258#endif
    245259                default:
    246                         talloc_free(smb_krb5);
     260                        talloc_free(tmp_ctx);
    247261                        return EINVAL;
    248262                }
    249                
     263
    250264                status = NT_STATUS_INVALID_PARAMETER;
    251265                switch (hi->proto) {
     
    257271                        break;
    258272                case KRB5_KRBHST_HTTP:
    259                         talloc_free(smb_krb5);
     273                        talloc_free(tmp_ctx);
    260274                        return EINVAL;
    261275                }
     
    266280
    267281                talloc_steal(smb_krb5, smb_krb5->sock);
    268                
    269                 remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen); 
     282
     283                remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen);
    270284                if (!remote_addr) {
    271285                        talloc_free(smb_krb5);
     
    278292                        continue;
    279293                }
    280                 talloc_free(remote_addr);
    281294
    282295                /* Setup the FDE, start listening for read events
     
    326339                        break;
    327340                case KRB5_KRBHST_HTTP:
    328                         talloc_free(smb_krb5);
     341                        talloc_free(tmp_ctx);
    329342                        return EINVAL;
    330343                }
    331344                while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
    332345                        if (tevent_loop_once(ev) != 0) {
    333                                 talloc_free(smb_krb5);
     346                                talloc_free(tmp_ctx);
    334347                                return EINVAL;
     348                        }
     349
     350                        /* After each and every event loop, reset the
     351                         * send_to_kdc pointers to what they were when
     352                         * we entered this loop.  That way, if a
     353                         * nested event has invalidated them, we put
     354                         * it back before we return to the heimdal
     355                         * code */
     356                        ret = krb5_set_send_to_kdc_func(context,
     357                                                        smb_krb5_send_and_recv_func,
     358                                                        data);
     359                        if (ret != 0) {
     360                                talloc_free(tmp_ctx);
     361                                return ret;
    335362                        }
    336363                }
     
    341368
    342369                if (!NT_STATUS_IS_OK(smb_krb5->status)) {
    343                         DEBUG(2,("Error reading smb_krb5 reply packet: %s\n", nt_errstr(smb_krb5->status)));
     370                        struct tsocket_address *addr = socket_address_to_tsocket_address(smb_krb5, remote_addr);
     371                        const char *addr_string = NULL;
     372                        if (addr) {
     373                                addr_string = tsocket_address_inet_addr_string(addr, smb_krb5);
     374                        } else {
     375                                addr_string = NULL;
     376                        }
     377                        DEBUG(2,("Error reading smb_krb5 reply packet: %s from %s\n", nt_errstr(smb_krb5->status),
     378                                 addr_string));
    344379                        talloc_free(smb_krb5);
    345380                        continue;
     
    348383                ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length);
    349384                if (ret) {
    350                         talloc_free(smb_krb5);
     385                        talloc_free(tmp_ctx);
    351386                        return ret;
    352387                }
    353388                talloc_free(smb_krb5);
    354                
     389
    355390                break;
    356391        }
     392        talloc_free(tmp_ctx);
    357393        if (a) {
    358394                return 0;
     
    361397}
    362398
    363 krb5_error_code smb_krb5_init_context(void *parent_ctx,
     399krb5_error_code
     400smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx,
     401                            struct loadparm_context *lp_ctx,
     402                            krb5_context *_krb5_context)
     403{
     404        krb5_error_code ret;
     405        char **config_files;
     406        const char *config_file, *realm;
     407        krb5_context krb5_ctx;
     408
     409        initialize_krb5_error_table();
     410
     411        ret = krb5_init_context(&krb5_ctx);
     412        if (ret) {
     413                DEBUG(1,("krb5_init_context failed (%s)\n",
     414                         error_message(ret)));
     415                return ret;
     416        }
     417
     418        config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf");
     419        if (!config_file) {
     420                krb5_free_context(krb5_ctx);
     421                return ENOMEM;
     422        }
     423
     424        /* Use our local krb5.conf file by default */
     425        ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);
     426        if (ret) {
     427                DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n",
     428                         smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
     429                krb5_free_context(krb5_ctx);
     430                return ret;
     431        }
     432
     433        ret = krb5_set_config_files(krb5_ctx, config_files);
     434        krb5_free_config_files(config_files);
     435        if (ret) {
     436                DEBUG(1,("krb5_set_config_files failed (%s)\n",
     437                         smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
     438                krb5_free_context(krb5_ctx);
     439                return ret;
     440        }
     441
     442        realm = lpcfg_realm(lp_ctx);
     443        if (realm != NULL) {
     444                ret = krb5_set_default_realm(krb5_ctx, realm);
     445                if (ret) {
     446                        DEBUG(1,("krb5_set_default_realm failed (%s)\n",
     447                                 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx)));
     448                        krb5_free_context(krb5_ctx);
     449                        return ret;
     450                }
     451        }
     452
     453        *_krb5_context = krb5_ctx;
     454        return 0;
     455}
     456
     457krb5_error_code smb_krb5_init_context(void *parent_ctx,
    364458                                      struct tevent_context *ev,
    365459                                      struct loadparm_context *lp_ctx,
    366                                        struct smb_krb5_context **smb_krb5_context)
     460                                      struct smb_krb5_context **smb_krb5_context)
    367461{
    368462        krb5_error_code ret;
    369463        TALLOC_CTX *tmp_ctx;
    370         char **config_files;
    371         const char *config_file;
    372        
     464
    373465        initialize_krb5_error_table();
    374        
     466
    375467        tmp_ctx = talloc_new(parent_ctx);
    376         *smb_krb5_context = talloc(tmp_ctx, struct smb_krb5_context);
     468        *smb_krb5_context = talloc_zero(tmp_ctx, struct smb_krb5_context);
    377469
    378470        if (!*smb_krb5_context || !tmp_ctx) {
     
    381473        }
    382474
    383         ret = krb5_init_context(&(*smb_krb5_context)->krb5_context);
    384         if (ret) {
    385                 DEBUG(1,("krb5_init_context failed (%s)\n",
     475        ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx,
     476                                          &(*smb_krb5_context)->krb5_context);
     477        if (ret) {
     478                DEBUG(1,("smb_krb5_context_init_basic failed (%s)\n",
    386479                         error_message(ret)));
    387480                talloc_free(tmp_ctx);
    388481                return ret;
    389         }
    390 
    391         talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy_1);
    392 
    393         config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf");
    394         if (!config_file) {
    395                 talloc_free(tmp_ctx);
    396                 return ENOMEM;
    397         }
    398                
    399         /* Use our local krb5.conf file by default */
    400         ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);
    401         if (ret) {
    402                 DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n",
    403                          smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    404                 talloc_free(tmp_ctx);
    405                 return ret;
    406         }
    407 
    408         ret = krb5_set_config_files((*smb_krb5_context)->krb5_context,
    409                                     config_files);
    410         krb5_free_config_files(config_files);
    411         if (ret) {
    412                 DEBUG(1,("krb5_set_config_files failed (%s)\n",
    413                          smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    414                 talloc_free(tmp_ctx);
    415                 return ret;
    416         }
    417                                                
    418         if (lp_realm(lp_ctx) && *lp_realm(lp_ctx)) {
    419                 char *upper_realm = strupper_talloc(tmp_ctx, lp_realm(lp_ctx));
    420                 if (!upper_realm) {
    421                         DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(lp_ctx)));
    422                         talloc_free(tmp_ctx);
    423                         return ENOMEM;
    424                 }
    425                 ret = krb5_set_default_realm((*smb_krb5_context)->krb5_context, upper_realm);
    426                 if (ret) {
    427                         DEBUG(1,("krb5_set_default_realm failed (%s)\n",
    428                                  smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    429                         talloc_free(tmp_ctx);
    430                         return ret;
    431                 }
    432482        }
    433483
    434484        /* TODO: Should we have a different name here? */
    435485        ret = krb5_initlog((*smb_krb5_context)->krb5_context, "Samba", &(*smb_krb5_context)->logf);
    436        
    437         if (ret) {
    438                 DEBUG(1,("krb5_initlog failed (%s)\n", 
     486
     487        if (ret) {
     488                DEBUG(1,("krb5_initlog failed (%s)\n",
    439489                         smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    440                 talloc_free(tmp_ctx);
    441                 return ret;
    442         }
    443 
    444         talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy_2);
    445 
    446         ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */,
     490                krb5_free_context((*smb_krb5_context)->krb5_context);
     491                talloc_free(tmp_ctx);
     492                return ret;
     493        }
     494
     495        talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy);
     496
     497        ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */,
    447498                               smb_krb5_debug_wrapper, smb_krb5_debug_close, NULL);
    448499        if (ret) {
    449                 DEBUG(1,("krb5_addlog_func failed (%s)\n", 
     500                DEBUG(1,("krb5_addlog_func failed (%s)\n",
    450501                         smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    451502                talloc_free(tmp_ctx);
     
    455506
    456507        /* Set use of our socket lib */
    457         ret = krb5_set_send_to_kdc_func((*smb_krb5_context)->krb5_context,
    458                                         smb_krb5_send_and_recv_func,
    459                                         ev);
    460         if (ret) {
    461                 DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
    462                          smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));
    463                 talloc_free(tmp_ctx);
    464                 return ret;
     508        if (ev) {
     509                struct tevent_context *previous_ev;
     510                ret = smb_krb5_context_set_event_ctx(*smb_krb5_context,
     511                                                     ev, &previous_ev);
     512                if (ret) {
     513                        talloc_free(tmp_ctx);
     514                        return ret;
     515                }
    465516        }
    466517
     
    471522
    472523        krb5_set_dns_canonicalize_hostname((*smb_krb5_context)->krb5_context,
    473                                            lp_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));
     524                                           lpcfg_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));
    474525
    475526        return 0;
    476527}
    477528
     529krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context,
     530                                               struct tevent_context *ev,
     531                                               struct tevent_context **previous_ev)
     532{
     533        int ret;
     534        if (!ev) {
     535                return EINVAL;
     536        }
     537
     538        *previous_ev = smb_krb5_context->current_ev;
     539
     540        smb_krb5_context->current_ev = talloc_reference(smb_krb5_context, ev);
     541        if (!smb_krb5_context->current_ev) {
     542                return ENOMEM;
     543        }
     544
     545        /* Set use of our socket lib */
     546        ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context,
     547                                        smb_krb5_send_and_recv_func,
     548                                        ev);
     549        if (ret) {
     550                TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     551                DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
     552                         smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx)));
     553                talloc_free(tmp_ctx);
     554                talloc_unlink(smb_krb5_context, smb_krb5_context->current_ev);
     555                smb_krb5_context->current_ev = NULL;
     556                return ret;
     557        }
     558        return 0;
     559}
     560
     561krb5_error_code smb_krb5_context_remove_event_ctx(struct smb_krb5_context *smb_krb5_context,
     562                                                  struct tevent_context *previous_ev,
     563                                                  struct tevent_context *ev)
     564{
     565        int ret;
     566        talloc_unlink(smb_krb5_context, ev);
     567        /* If there was a mismatch with things happening on a stack, then don't wipe things */
     568        smb_krb5_context->current_ev = previous_ev;
     569        /* Set use of our socket lib */
     570        ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context,
     571                                        smb_krb5_send_and_recv_func,
     572                                        previous_ev);
     573        if (ret) {
     574                TALLOC_CTX *tmp_ctx = talloc_new(NULL);
     575                DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",
     576                         smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx)));
     577                talloc_free(tmp_ctx);
     578                return ret;
     579        }
     580        return 0;
     581}
  • vendor/current/source4/auth/kerberos/krb5_init_context.h

    r414 r740  
    2121        krb5_context krb5_context;
    2222        krb5_log_facility *logf;
     23        struct tevent_context *current_ev;
    2324};
    2425       
    2526struct tevent_context;
    2627struct loadparm_context;
     28
     29krb5_error_code
     30smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx,
     31                            struct loadparm_context *lp_ctx,
     32                            krb5_context *_krb5_context);
     33
    2734krb5_error_code smb_krb5_init_context(void *parent_ctx, struct tevent_context *ev,
    2835                                      struct loadparm_context *lp_ctx,
    2936                                      struct smb_krb5_context **smb_krb5_context);
    30 void smb_krb5_free_context(struct smb_krb5_context *smb_krb5_context);
    3137
    3238krb5_error_code smb_krb5_send_and_recv_func(krb5_context context,
  • vendor/current/source4/auth/ntlm/auth.c

    r414 r740  
    2020
    2121#include "includes.h"
     22#include <tevent.h>
     23#include "../lib/util/tevent_ntstatus.h"
    2224#include "../lib/util/dlinklist.h"
    2325#include "auth/auth.h"
    2426#include "auth/ntlm/auth_proto.h"
    25 #include "lib/events/events.h"
    2627#include "param/param.h"
     28#include "dsdb/samdb/samdb.h"
     29
    2730
    2831/***************************************************************************
     
    4346 Set a fixed challenge
    4447***************************************************************************/
    45 bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)
     48_PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)
    4649{
    4750        return auth_ctx->challenge.may_be_modified;
     
    5255 Returns a const char of length 8 bytes.
    5356****************************************************************************/
    54 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal)
     57_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8])
    5558{
    5659        NTSTATUS nt_status;
    5760        struct auth_method_context *method;
    5861
    59         if (auth_ctx->challenge.data.length) {
     62        if (auth_ctx->challenge.data.length == 8) {
    6063                DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n",
    6164                          auth_ctx->challenge.set_by));
    62                 *_chal = auth_ctx->challenge.data.data;
     65                memcpy(chal, auth_ctx->challenge.data.data, 8);
    6366                return NT_STATUS_OK;
    6467        }
    6568
    6669        for (method = auth_ctx->methods; method; method = method->next) {
    67                 DATA_BLOB challenge = data_blob(NULL,0);
    68 
    69                 nt_status = method->ops->get_challenge(method, auth_ctx, &challenge);
     70                nt_status = method->ops->get_challenge(method, auth_ctx, chal);
    7071                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    7172                        continue;
     
    7475                NT_STATUS_NOT_OK_RETURN(nt_status);
    7576
    76                 if (challenge.length != 8) {
    77                         DEBUG(0, ("auth_get_challenge: invalid challenge (length %u) by mothod [%s]\n",
    78                                 (unsigned)challenge.length, method->ops->name));
    79                         return NT_STATUS_INTERNAL_ERROR;
    80                 }
    81 
    82                 auth_ctx->challenge.data        = challenge;
     77                auth_ctx->challenge.data        = data_blob_talloc(auth_ctx, chal, 8);
     78                NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
    8379                auth_ctx->challenge.set_by      = method->ops->name;
    8480
     
    8783
    8884        if (!auth_ctx->challenge.set_by) {
    89                 uint8_t chal[8];
    9085                generate_random_buffer(chal, 8);
    9186
     
    10095                 auth_ctx->challenge.set_by));
    10196
    102         *_chal = auth_ctx->challenge.data.data;
    10397        return NT_STATUS_OK;
    10498}
    10599
    106100/****************************************************************************
    107  Try to get a challenge out of the various authentication modules.
    108  Returns a const char of length 8 bytes.
     101Used in the gensec_gssapi and gensec_krb5 server-side code, where the
     102PAC isn't available, and for tokenGroups in the DSDB stack.
     103
     104 Supply either a principal or a DN
    109105****************************************************************************/
    110 _PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx,
    111                                                   struct auth_context *auth_ctx,
    112                                                   const char *principal,
    113                                                   struct auth_serversupplied_info **server_info)
     106_PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
     107                                                 struct auth_context *auth_ctx,
     108                                                 const char *principal,
     109                                                 struct ldb_dn *user_dn,
     110                                                 struct auth_user_info_dc **user_info_dc)
    114111{
    115112        NTSTATUS nt_status;
     
    117114
    118115        for (method = auth_ctx->methods; method; method = method->next) {
    119                 if (!method->ops->get_server_info_principal) {
     116                if (!method->ops->get_user_info_dc_principal) {
    120117                        continue;
    121118                }
    122119
    123                 nt_status = method->ops->get_server_info_principal(mem_ctx, auth_ctx, principal, server_info);
     120                nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc);
    124121                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    125122                        continue;
    126123                }
    127124
    128                 NT_STATUS_NOT_OK_RETURN(nt_status);
    129 
    130                 break;
    131         }
    132 
    133         return NT_STATUS_OK;
    134 }
    135 
    136 struct auth_check_password_sync_state {
    137         bool finished;
    138         NTSTATUS status;
    139         struct auth_serversupplied_info *server_info;
    140 };
    141 
    142 static void auth_check_password_sync_callback(struct auth_check_password_request *req,
    143                                               void *private_data)
    144 {
    145         struct auth_check_password_sync_state *s = talloc_get_type(private_data,
    146                                                    struct auth_check_password_sync_state);
    147 
    148         s->finished = true;
    149         s->status = auth_check_password_recv(req, s, &s->server_info);
     125                return nt_status;
     126        }
     127
     128        return NT_STATUS_NOT_IMPLEMENTED;
    150129}
    151130
     
    155134 *
    156135 * Check a user's password, as given in the user_info struct and return various
    157  * interesting details in the server_info struct.
    158  *
    159  * The return value takes precedence over the contents of the server_info
     136 * interesting details in the user_info_dc struct.
     137 *
     138 * The return value takes precedence over the contents of the user_info_dc
    160139 * struct.  When the return is other than NT_STATUS_OK the contents
    161140 * of that structure is undefined.
     
    168147 * @param user_info Contains the user supplied components, including the passwords.
    169148 *
    170  * @param mem_ctx The parent memory context for the server_info structure
    171  *
    172  * @param server_info If successful, contains information about the authentication,
     149 * @param mem_ctx The parent memory context for the user_info_dc structure
     150 *
     151 * @param user_info_dc If successful, contains information about the authentication,
    173152 *                    including a SAM_ACCOUNT struct describing the user.
    174153 *
     
    180159                             TALLOC_CTX *mem_ctx,
    181160                             const struct auth_usersupplied_info *user_info,
    182                              struct auth_serversupplied_info **server_info)
    183 {
    184         struct auth_check_password_sync_state *sync_state;
     161                             struct auth_user_info_dc **user_info_dc)
     162{
     163        struct tevent_req *subreq;
     164        struct tevent_context *ev;
     165        bool ok;
    185166        NTSTATUS status;
    186167
    187         sync_state = talloc_zero(auth_ctx, struct auth_check_password_sync_state);
    188         NT_STATUS_HAVE_NO_MEMORY(sync_state);
    189 
    190         auth_check_password_send(auth_ctx, user_info, auth_check_password_sync_callback, sync_state);
    191 
    192         while (!sync_state->finished) {
    193                 event_loop_once(auth_ctx->event_ctx);
    194         }
    195 
    196         status = sync_state->status;
    197 
    198         if (NT_STATUS_IS_OK(status)) {
    199                 *server_info = talloc_steal(mem_ctx, sync_state->server_info);
    200         }
    201 
    202         talloc_free(sync_state);
     168        /*TODO: create a new event context here! */
     169        ev = auth_ctx->event_ctx;
     170
     171        subreq = auth_check_password_send(mem_ctx,
     172                                          ev,
     173                                          auth_ctx,
     174                                          user_info);
     175        if (subreq == NULL) {
     176                return NT_STATUS_NO_MEMORY;
     177        }
     178
     179        ok = tevent_req_poll(subreq, ev);
     180        if (!ok) {
     181                return NT_STATUS_INTERNAL_ERROR;
     182        }
     183
     184        status = auth_check_password_recv(subreq, mem_ctx, user_info_dc);
     185        TALLOC_FREE(subreq);
     186
    203187        return status;
    204188}
    205189
    206 struct auth_check_password_request {
     190struct auth_check_password_state {
    207191        struct auth_context *auth_ctx;
    208192        const struct auth_usersupplied_info *user_info;
    209         struct auth_serversupplied_info *server_info;
     193        struct auth_user_info_dc *user_info_dc;
    210194        struct auth_method_context *method;
    211         NTSTATUS status;
    212         struct {
    213                 void (*fn)(struct auth_check_password_request *req, void *private_data);
    214                 void *private_data;
    215         } callback;
    216195};
    217196
    218 static void auth_check_password_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te,
    219                                                     struct timeval t, void *ptr)
    220 {
    221         struct auth_check_password_request *req = talloc_get_type(ptr, struct auth_check_password_request);
    222         req->status = req->method->ops->check_password(req->method, req, req->user_info, &req->server_info);
    223         req->callback.fn(req, req->callback.private_data);
    224 }
    225 
     197static void auth_check_password_async_trigger(struct tevent_context *ev,
     198                                              struct tevent_immediate *im,
     199                                              void *private_data);
    226200/**
    227201 * Check a user's Plaintext, LM or NTLM password.
     
    229203 *
    230204 * Check a user's password, as given in the user_info struct and return various
    231  * interesting details in the server_info struct.
    232  *
    233  * The return value takes precedence over the contents of the server_info
     205 * interesting details in the user_info_dc struct.
     206 *
     207 * The return value takes precedence over the contents of the user_info_dc
    234208 * struct.  When the return is other than NT_STATUS_OK the contents
    235209 * of that structure is undefined.
     210 *
     211 * @param mem_ctx The memory context the request should operate on
     212 *
     213 * @param ev The tevent context the request should operate on
    236214 *
    237215 * @param auth_ctx Supplies the challenges and some other data.
     
    242220 * @param user_info Contains the user supplied components, including the passwords.
    243221 *
    244  * @param callback A callback function which will be called when the operation is finished.
    245  *                 The callback function needs to call auth_check_password_recv() to get the return values
    246  *
    247  * @param private_data A private pointer which will ba passed to the callback function
     222 * @return The request handle or NULL on no memory error.
    248223 *
    249224 **/
    250225
    251 _PUBLIC_ void auth_check_password_send(struct auth_context *auth_ctx,
    252                               const struct auth_usersupplied_info *user_info,
    253                               void (*callback)(struct auth_check_password_request *req, void *private_data),
    254                               void *private_data)
    255 {
     226_PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
     227                                struct tevent_context *ev,
     228                                struct auth_context *auth_ctx,
     229                                const struct auth_usersupplied_info *user_info)
     230{
     231        struct tevent_req *req;
     232        struct auth_check_password_state *state;
    256233        /* if all the modules say 'not for me' this is reasonable */
    257234        NTSTATUS nt_status;
     235        uint8_t chal[8];
     236        struct auth_usersupplied_info *user_info_tmp;
     237        struct tevent_immediate *im;
     238
     239        DEBUG(3,("auth_check_password_send: "
     240                 "Checking password for unmapped user [%s]\\[%s]@[%s]\n",
     241                 user_info->client.domain_name, user_info->client.account_name,
     242                 user_info->workstation_name));
     243
     244        req = tevent_req_create(mem_ctx, &state,
     245                                struct auth_check_password_state);
     246        if (req == NULL) {
     247                return NULL;
     248        }
     249
     250        state->auth_ctx         = auth_ctx;
     251        state->user_info        = user_info;
     252
     253        if (!user_info->mapped_state) {
     254                nt_status = map_user_info(req, lpcfg_workgroup(auth_ctx->lp_ctx),
     255                                          user_info, &user_info_tmp);
     256                if (tevent_req_nterror(req, nt_status)) {
     257                        return tevent_req_post(req, ev);
     258                }
     259                user_info = user_info_tmp;
     260                state->user_info = user_info_tmp;
     261        }
     262
     263        DEBUGADD(3,("auth_check_password_send: "
     264                    "mapped user is: [%s]\\[%s]@[%s]\n",
     265                    user_info->mapped.domain_name,
     266                    user_info->mapped.account_name,
     267                    user_info->workstation_name));
     268
     269        nt_status = auth_get_challenge(auth_ctx, chal);
     270        if (tevent_req_nterror(req, nt_status)) {
     271                DEBUG(0,("auth_check_password_send: "
     272                         "Invalid challenge (length %u) stored for "
     273                         "this auth context set_by %s - cannot continue: %s\n",
     274                        (unsigned)auth_ctx->challenge.data.length,
     275                        auth_ctx->challenge.set_by,
     276                        nt_errstr(nt_status)));
     277                return tevent_req_post(req, ev);
     278        }
     279
     280        if (auth_ctx->challenge.set_by) {
     281                DEBUG(10,("auth_check_password_send: "
     282                          "auth_context challenge created by %s\n",
     283                          auth_ctx->challenge.set_by));
     284        }
     285
     286        DEBUG(10, ("auth_check_password_send: challenge is: \n"));
     287        dump_data(5, auth_ctx->challenge.data.data,
     288                  auth_ctx->challenge.data.length);
     289
     290        im = tevent_create_immediate(state);
     291        if (tevent_req_nomem(im, req)) {
     292                return tevent_req_post(req, ev);
     293        }
     294
     295        tevent_schedule_immediate(im,
     296                                  auth_ctx->event_ctx,
     297                                  auth_check_password_async_trigger,
     298                                  req);
     299        return req;
     300}
     301
     302static void auth_check_password_async_trigger(struct tevent_context *ev,
     303                                              struct tevent_immediate *im,
     304                                              void *private_data)
     305{
     306        struct tevent_req *req =
     307                talloc_get_type_abort(private_data, struct tevent_req);
     308        struct auth_check_password_state *state =
     309                tevent_req_data(req, struct auth_check_password_state);
     310        NTSTATUS status;
    258311        struct auth_method_context *method;
    259         const uint8_t *challenge;
    260         struct auth_usersupplied_info *user_info_tmp;
    261         struct auth_check_password_request *req = NULL;
    262 
    263         DEBUG(3,   ("auth_check_password_send:  Checking password for unmapped user [%s]\\[%s]@[%s]\n",
    264                     user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
    265 
    266         req = talloc_zero(auth_ctx, struct auth_check_password_request);
    267         if (!req) {
    268                 callback(NULL, private_data);
     312
     313        status = NT_STATUS_OK;
     314
     315        for (method=state->auth_ctx->methods; method; method = method->next) {
     316
     317                /* we fill in state->method here so debug messages in
     318                   the callers know which method failed */
     319                state->method = method;
     320
     321                /* check if the module wants to check the password */
     322                status = method->ops->want_check(method, req, state->user_info);
     323                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     324                        DEBUG(11,("auth_check_password_send: "
     325                                  "%s had nothing to say\n",
     326                                  method->ops->name));
     327                        continue;
     328                }
     329
     330                if (tevent_req_nterror(req, status)) {
     331                        return;
     332                }
     333
     334                status = method->ops->check_password(method,
     335                                                     state,
     336                                                     state->user_info,
     337                                                     &state->user_info_dc);
     338                if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     339                        /* the backend has handled the request */
     340                        break;
     341                }
     342        }
     343
     344        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     345                /* don't expose the NT_STATUS_NOT_IMPLEMENTED
     346                   internals */
     347                status = NT_STATUS_NO_SUCH_USER;
     348        }
     349
     350        if (tevent_req_nterror(req, status)) {
    269351                return;
    270352        }
    271         req->auth_ctx                   = auth_ctx;
    272         req->user_info                  = user_info;
    273         req->callback.fn                = callback;
    274         req->callback.private_data      = private_data;
    275 
    276         if (!user_info->mapped_state) {
    277                 nt_status = map_user_info(req, lp_workgroup(auth_ctx->lp_ctx), user_info, &user_info_tmp);
    278                 if (!NT_STATUS_IS_OK(nt_status)) goto failed;
    279                 user_info = user_info_tmp;
    280                 req->user_info  = user_info_tmp;
    281         }
    282 
    283         DEBUGADD(3,("auth_check_password_send:  mapped user is: [%s]\\[%s]@[%s]\n",
    284                     user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name));
    285 
    286         nt_status = auth_get_challenge(auth_ctx, &challenge);
    287         if (!NT_STATUS_IS_OK(nt_status)) {
    288                 DEBUG(0, ("auth_check_password_send:  Invalid challenge (length %u) stored for this auth context set_by %s - cannot continue: %s\n",
    289                         (unsigned)auth_ctx->challenge.data.length, auth_ctx->challenge.set_by, nt_errstr(nt_status)));
    290                 goto failed;
    291         }
    292 
    293         if (auth_ctx->challenge.set_by) {
    294                 DEBUG(10, ("auth_check_password_send: auth_context challenge created by %s\n",
    295                                         auth_ctx->challenge.set_by));
    296         }
    297 
    298         DEBUG(10, ("auth_check_password_send: challenge is: \n"));
    299         dump_data(5, auth_ctx->challenge.data.data, auth_ctx->challenge.data.length);
    300 
    301         nt_status = NT_STATUS_NO_SUCH_USER; /* If all the modules say 'not for me', then this is reasonable */
    302         for (method = auth_ctx->methods; method; method = method->next) {
    303                 NTSTATUS result;
    304                 struct tevent_timer *te = NULL;
    305 
    306                 /* check if the module wants to chek the password */
    307                 result = method->ops->want_check(method, req, user_info);
    308                 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
    309                         DEBUG(11,("auth_check_password_send: %s had nothing to say\n", method->ops->name));
    310                         continue;
    311                 }
    312 
    313                 nt_status = result;
    314                 req->method     = method;
    315 
    316                 if (!NT_STATUS_IS_OK(nt_status)) break;
    317 
    318                 te = event_add_timed(auth_ctx->event_ctx, req,
    319                                      timeval_zero(),
    320                                      auth_check_password_async_timed_handler, req);
    321                 if (!te) {
    322                         nt_status = NT_STATUS_NO_MEMORY;
    323                         goto failed;
    324                 }
    325                 return;
    326         }
    327 
    328 failed:
    329         req->status = nt_status;
    330         req->callback.fn(req, req->callback.private_data);
     353
     354        tevent_req_done(req);
    331355}
    332356
     
    335359 * async receive function
    336360 *
    337  * The return value takes precedence over the contents of the server_info
     361 * The return value takes precedence over the contents of the user_info_dc
    338362 * struct.  When the return is other than NT_STATUS_OK the contents
    339363 * of that structure is undefined.
    340364 *
    341365 *
    342  * @param req The async auth_check_password state, passes to the callers callback function
    343  *
    344  * @param mem_ctx The parent memory context for the server_info structure
    345  *
    346  * @param server_info If successful, contains information about the authentication,
     366 * @param req The async request state
     367 *
     368 * @param mem_ctx The parent memory context for the user_info_dc structure
     369 *
     370 * @param user_info_dc If successful, contains information about the authentication,
    347371 *                    including a SAM_ACCOUNT struct describing the user.
    348372 *
     
    351375 **/
    352376
    353 _PUBLIC_ NTSTATUS auth_check_password_recv(struct auth_check_password_request *req,
     377_PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
    354378                                  TALLOC_CTX *mem_ctx,
    355                                   struct auth_serversupplied_info **server_info)
    356 {
     379                                  struct auth_user_info_dc **user_info_dc)
     380{
     381        struct auth_check_password_state *state =
     382                tevent_req_data(req, struct auth_check_password_state);
    357383        NTSTATUS status;
    358384
    359         NT_STATUS_HAVE_NO_MEMORY(req);
    360 
    361         if (NT_STATUS_IS_OK(req->status)) {
    362                 DEBUG(5,("auth_check_password_recv: %s authentication for user [%s\\%s] succeeded\n",
    363                          req->method->ops->name, req->server_info->domain_name, req->server_info->account_name));
    364 
    365                 *server_info = talloc_steal(mem_ctx, req->server_info);
    366         } else {
    367                 DEBUG(2,("auth_check_password_recv: %s authentication for user [%s\\%s] FAILED with error %s\n",
    368                          (req->method ? req->method->ops->name : "NO_METHOD"),
    369                          req->user_info->mapped.domain_name,
    370                          req->user_info->mapped.account_name,
    371                          nt_errstr(req->status)));
    372         }
    373 
    374         status = req->status;
    375         talloc_free(req);
    376         return status;
     385        if (tevent_req_is_nterror(req, &status)) {
     386                DEBUG(2,("auth_check_password_recv: "
     387                         "%s authentication for user [%s\\%s] "
     388                         "FAILED with error %s\n",
     389                         (state->method ? state->method->ops->name : "NO_METHOD"),
     390                         state->user_info->mapped.domain_name,
     391                         state->user_info->mapped.account_name,
     392                         nt_errstr(status)));
     393                tevent_req_received(req);
     394                return status;
     395        }
     396
     397        DEBUG(5,("auth_check_password_recv: "
     398                 "%s authentication for user [%s\\%s] succeeded\n",
     399                 state->method->ops->name,
     400                 state->user_info_dc->info->domain_name,
     401                 state->user_info_dc->info->account_name));
     402
     403        *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
     404
     405        tevent_req_received(req);
     406        return NT_STATUS_OK;
     407}
     408
     409/* Wrapper because we don't want to expose all callers to needing to
     410 * know that session_info is generated from the main ldb */
     411static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx,
     412                                                   struct auth_context *auth_context,
     413                                                   struct auth_user_info_dc *user_info_dc,
     414                                                   uint32_t session_info_flags,
     415                                                   struct auth_session_info **session_info)
     416{
     417        return auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
     418                                          auth_context->sam_ctx, user_info_dc,
     419                                          session_info_flags, session_info);
    377420}
    378421
    379422/***************************************************************************
    380423 Make a auth_info struct for the auth subsystem
    381  - Allow the caller to specify the methods to use
     424 - Allow the caller to specify the methods to use, including optionally the SAM to use
    382425***************************************************************************/
    383426_PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
    384                                      struct tevent_context *ev,
    385                                      struct messaging_context *msg,
    386                                      struct loadparm_context *lp_ctx,
    387                                      struct auth_context **auth_ctx)
     427                                              struct tevent_context *ev,
     428                                              struct messaging_context *msg,
     429                                              struct loadparm_context *lp_ctx,
     430                                              struct ldb_context *sam_ctx,
     431                                              struct auth_context **auth_ctx)
    388432{
    389433        int i;
    390434        struct auth_context *ctx;
    391435
    392         auth_init();
    393 
    394         if (!methods) {
    395                 DEBUG(0,("auth_context_create: No auth method list!?\n"));
    396                 return NT_STATUS_INTERNAL_ERROR;
    397         }
     436        auth4_init();
    398437
    399438        if (!ev) {
    400439                DEBUG(0,("auth_context_create: called with out event context\n"));
    401                 return NT_STATUS_INTERNAL_ERROR;
    402         }
    403 
    404         if (!msg) {
    405                 DEBUG(0,("auth_context_create: called with out messaging context\n"));
    406440                return NT_STATUS_INTERNAL_ERROR;
    407441        }
     
    417451        ctx->lp_ctx                     = lp_ctx;
    418452
    419         for (i=0; methods[i] ; i++) {
     453        if (sam_ctx) {
     454                ctx->sam_ctx = sam_ctx;
     455        } else {
     456                ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0);
     457        }
     458
     459        for (i=0; methods && methods[i] ; i++) {
    420460                struct auth_method_context *method;
    421461
     
    434474        }
    435475
    436         if (!ctx->methods) {
    437                 return NT_STATUS_INTERNAL_ERROR;
    438         }
    439 
    440476        ctx->check_password = auth_check_password;
    441477        ctx->get_challenge = auth_get_challenge;
    442478        ctx->set_challenge = auth_context_set_challenge;
    443479        ctx->challenge_may_be_modified = auth_challenge_may_be_modified;
    444         ctx->get_server_info_principal = auth_get_server_info_principal;
     480        ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal;
     481        ctx->generate_session_info = auth_generate_session_info_wrapper;
    445482
    446483        *auth_ctx = ctx;
     
    448485        return NT_STATUS_OK;
    449486}
     487
     488const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
     489{
     490        const char **auth_methods = NULL;
     491        switch (lpcfg_server_role(lp_ctx)) {
     492        case ROLE_STANDALONE:
     493                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);
     494                break;
     495        case ROLE_DOMAIN_MEMBER:
     496                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);
     497                break;
     498        case ROLE_DOMAIN_CONTROLLER:
     499                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL);
     500                break;
     501        }
     502        return auth_methods;
     503}
     504
    450505/***************************************************************************
    451506 Make a auth_info struct for the auth subsystem
    452507 - Uses default auth_methods, depending on server role and smb.conf settings
    453508***************************************************************************/
    454 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 
     509_PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
    455510                             struct tevent_context *ev,
    456511                             struct messaging_context *msg,
     
    458513                             struct auth_context **auth_ctx)
    459514{
    460         const char **auth_methods = NULL;
    461         switch (lp_server_role(lp_ctx)) {
    462         case ROLE_STANDALONE:
    463                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);
    464                 break;
    465         case ROLE_DOMAIN_MEMBER:
    466                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);
    467                 break;
    468         case ROLE_DOMAIN_CONTROLLER:
    469                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL);
    470                 break;
    471         }
    472         return auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, auth_ctx);
    473 }
    474 
     515        NTSTATUS status;
     516        const char **auth_methods;
     517        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     518        if (!tmp_ctx) {
     519                return NT_STATUS_NO_MEMORY;
     520        }
     521
     522        auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
     523        if (!auth_methods) {
     524                return NT_STATUS_INVALID_PARAMETER;
     525        }
     526        status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
     527        talloc_free(tmp_ctx);
     528        return status;
     529}
     530
     531/* Create an auth context from an open LDB.
     532
     533   This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups)
     534
     535 */
     536NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx)
     537{
     538        NTSTATUS status;
     539        const char **auth_methods;
     540        struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
     541        struct tevent_context *ev = ldb_get_event_context(ldb);
     542
     543        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     544        if (!tmp_ctx) {
     545                return NT_STATUS_NO_MEMORY;
     546        }
     547
     548        auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
     549        if (!auth_methods) {
     550                return NT_STATUS_INVALID_PARAMETER;
     551        }
     552        status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx);
     553        talloc_free(tmp_ctx);
     554        return status;
     555}
    475556
    476557/* the list of currently registered AUTH backends */
     
    545626                sizeof(struct auth_context),
    546627                sizeof(struct auth_usersupplied_info),
    547                 sizeof(struct auth_serversupplied_info)
     628                sizeof(struct auth_user_info_dc)
    548629        };
    549630
     
    551632}
    552633
    553 _PUBLIC_ NTSTATUS auth_init(void)
     634_PUBLIC_ NTSTATUS auth4_init(void)
    554635{
    555636        static bool initialized = false;
    556         extern NTSTATUS auth_developer_init(void);
    557         extern NTSTATUS auth_winbind_init(void);
    558         extern NTSTATUS auth_anonymous_init(void);
    559         extern NTSTATUS auth_unix_init(void);
    560         extern NTSTATUS auth_sam_init(void);
    561         extern NTSTATUS auth_server_init(void);
    562 
    563         init_module_fn static_init[] = { STATIC_auth_MODULES };
     637#define _MODULE_PROTO(init) extern NTSTATUS init(void);
     638        STATIC_auth4_MODULES_PROTO;
     639        init_module_fn static_init[] = { STATIC_auth4_MODULES };
    564640       
    565641        if (initialized) return NT_STATUS_OK;
     
    570646        return NT_STATUS_OK;   
    571647}
    572 
    573 NTSTATUS server_service_auth_init(void)
    574 {
    575         return auth_init();
    576 }
  • vendor/current/source4/auth/ntlm/auth_anonymous.c

    r414 r740  
    5353                                         TALLOC_CTX *mem_ctx,
    5454                                         const struct auth_usersupplied_info *user_info,
    55                                          struct auth_serversupplied_info **_server_info)
     55                                         struct auth_user_info_dc **_user_info_dc)
    5656{
    57         return auth_anonymous_server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), _server_info);
     57        return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc);
    5858}
    5959
  • vendor/current/source4/auth/ntlm/auth_developer.c

    r414 r740  
    2424#include "auth/ntlm/auth_proto.h"
    2525#include "libcli/security/security.h"
    26 #include "librpc/gen_ndr/ndr_samr.h"
    2726
    2827static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx,
     
    4948                                                TALLOC_CTX *mem_ctx,
    5049                                                const struct auth_usersupplied_info *user_info,
    51                                                 struct auth_serversupplied_info **_server_info)
     50                                                struct auth_user_info_dc **_user_info_dc)
    5251{
    5352        NTSTATUS nt_status;
    54         struct auth_serversupplied_info *server_info;
     53        struct auth_user_info_dc *user_info_dc;
     54        struct auth_user_info *info;
    5555        uint32_t error_num;
    5656        const char *user;
     
    6767        NT_STATUS_NOT_OK_RETURN(nt_status);
    6868
    69         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    70         NT_STATUS_HAVE_NO_MEMORY(server_info);
    71 
    72         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    73         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    74 
    75         /* is this correct? */
    76         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    77         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    78 
    79         server_info->n_domain_groups = 0;
    80         server_info->domain_groups = NULL;
     69        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     70        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     71
     72        /* This returns a pointer to a struct dom_sid, which is the
     73         * same as a 1 element list of struct dom_sid */
     74        user_info_dc->num_sids = 1;
     75        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
     76        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
    8177
    8278        /* annoying, but the Anonymous really does have a session key,
    8379           and it is all zeros! */
    84         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    85         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    86 
    87         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    88         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    89 
    90         data_blob_clear(&server_info->user_session_key);
    91         data_blob_clear(&server_info->lm_session_key);
    92 
    93         server_info->account_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user);
    94         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    95 
    96         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
    97         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    98 
    99         server_info->full_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s Anonymous Logon", user);
    100         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    101 
    102         server_info->logon_script = talloc_strdup(server_info, "");
    103         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    104 
    105         server_info->profile_path = talloc_strdup(server_info, "");
    106         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    107 
    108         server_info->home_directory = talloc_strdup(server_info, "");
    109         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    110 
    111         server_info->home_drive = talloc_strdup(server_info, "");
    112         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    113 
    114         server_info->last_logon = 0;
    115         server_info->last_logoff = 0;
    116         server_info->acct_expiry = 0;
    117         server_info->last_password_change = 0;
    118         server_info->allow_password_change = 0;
    119         server_info->force_password_change = 0;
    120 
    121         server_info->logon_count = 0;
    122         server_info->bad_password_count = 0;
    123 
    124         server_info->acct_flags = ACB_NORMAL;
    125 
    126         server_info->authenticated = false;
    127 
    128         *_server_info = server_info;
     80        user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     81        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
     82
     83        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     84        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
     85
     86        data_blob_clear(&user_info_dc->user_session_key);
     87        data_blob_clear(&user_info_dc->lm_session_key);
     88
     89        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     90        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     91
     92        info->account_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user);
     93        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     94
     95        info->domain_name = talloc_strdup(user_info_dc, "NT AUTHORITY");
     96        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     97
     98        info->full_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s Anonymous Logon", user);
     99        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     100
     101        info->logon_script = talloc_strdup(user_info_dc, "");
     102        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     103
     104        info->profile_path = talloc_strdup(user_info_dc, "");
     105        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     106
     107        info->home_directory = talloc_strdup(user_info_dc, "");
     108        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     109
     110        info->home_drive = talloc_strdup(user_info_dc, "");
     111        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     112
     113        info->last_logon = 0;
     114        info->last_logoff = 0;
     115        info->acct_expiry = 0;
     116        info->last_password_change = 0;
     117        info->allow_password_change = 0;
     118        info->force_password_change = 0;
     119
     120        info->logon_count = 0;
     121        info->bad_password_count = 0;
     122
     123        info->acct_flags = ACB_NORMAL;
     124
     125        info->authenticated = true;
     126
     127        *_user_info_dc = user_info_dc;
    129128
    130129        return nt_status;
     
    152151 * @return NT_STATUS_UNSUCCESSFUL
    153152 **/
    154 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
    155 {
    156         DATA_BLOB blob;
     153static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
     154{
    157155        const char *challenge = "I am a teapot";
    158156
    159         blob = data_blob_talloc(mem_ctx, challenge, 8);
    160         NT_STATUS_HAVE_NO_MEMORY(blob.data);
    161 
    162         *_blob = blob;
     157        memcpy(chal, challenge, 8);
     158
    163159        return NT_STATUS_OK;
    164160}
     
    175171                                               TALLOC_CTX *mem_ctx,
    176172                                               const struct auth_usersupplied_info *user_info,
    177                                                struct auth_serversupplied_info **_server_info)
     173                                               struct auth_user_info_dc **_user_info_dc)
    178174{
    179175        /* don't handle any users */
  • vendor/current/source4/auth/ntlm/auth_sam.c

    r414 r740  
    2121
    2222#include "includes.h"
    23 #include "librpc/gen_ndr/ndr_netlogon.h"
    2423#include "system/time.h"
    25 #include "lib/ldb/include/ldb.h"
    26 #include "../lib/util/util_ldb.h"
     24#include <ldb.h>
     25#include "libcli/ldap/ldap_ndr.h"
     26#include "libcli/security/security.h"
    2727#include "auth/auth.h"
    2828#include "../libcli/auth/ntlm_check.h"
     
    3030#include "auth/auth_sam.h"
    3131#include "dsdb/samdb/samdb.h"
    32 #include "libcli/security/security.h"
    33 #include "libcli/ldap/ldap_ndr.h"
     32#include "dsdb/common/util.h"
    3433#include "param/param.h"
     34#include "librpc/gen_ndr/ndr_irpc_c.h"
     35#include "lib/messaging/irpc.h"
    3536
    3637extern const char *user_attrs[];
     
    4950
    5051        /* pull the user attributes */
    51         ret = gendb_search_single_extended_dn(sam_ctx, mem_ctx, domain_dn, LDB_SCOPE_SUBTREE,
    52                                               ret_msg, user_attrs,
    53                                               "(&(sAMAccountName=%s)(objectclass=user))",
    54                                               ldb_binary_encode_string(mem_ctx, account_name));
     52        ret = dsdb_search_one(sam_ctx, mem_ctx, ret_msg, domain_dn, LDB_SCOPE_SUBTREE,
     53                              user_attrs,
     54                              DSDB_SEARCH_SHOW_EXTENDED_DN,
     55                              "(&(sAMAccountName=%s)(objectclass=user))",
     56                              ldb_binary_encode_string(mem_ctx, account_name));
    5557        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    5658                DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n",
     
    99101                *user_sess_key = data_blob(NULL, 0);
    100102                status = hash_password_check(mem_ctx,
    101                                              lp_lanman_auth(auth_context->lp_ctx),
     103                                             lpcfg_lanman_auth(auth_context->lp_ctx),
    102104                                             user_info->password.hash.lanman,
    103105                                             user_info->password.hash.nt,
     
    109111        case AUTH_PASSWORD_RESPONSE:
    110112                status = ntlm_password_check(mem_ctx,
    111                                              lp_lanman_auth(auth_context->lp_ctx),
    112                                                  lp_ntlm_auth(auth_context->lp_ctx),
     113                                             lpcfg_lanman_auth(auth_context->lp_ctx),
     114                                                 lpcfg_ntlm_auth(auth_context->lp_ctx),
    113115                                             user_info->logon_parameters,
    114116                                             &auth_context->challenge.data,
     
    135137
    136138
     139/*
     140  send a message to the drepl server telling it to initiate a
     141  REPL_SECRET getncchanges extended op to fetch the users secrets
     142 */
     143static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
     144                                         struct ldb_dn *user_dn)
     145{
     146        struct dcerpc_binding_handle *irpc_handle;
     147        struct drepl_trigger_repl_secret r;
     148        struct tevent_req *req;
     149
     150        irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx,
     151                                                  "dreplsrv",
     152                                                  &ndr_table_irpc);
     153        if (irpc_handle == NULL) {
     154                DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
     155                return;
     156        }
     157
     158        r.in.user_dn = ldb_dn_get_linearized(user_dn);
     159
     160        req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx,
     161                                                      auth_context->event_ctx,
     162                                                      irpc_handle,
     163                                                      &r);
     164
     165        /* we aren't interested in a reply */
     166        talloc_free(req);
     167        talloc_free(irpc_handle);
     168}
     169
    137170
    138171static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
     
    146179        NTSTATUS nt_status;
    147180
    148         uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
     181        uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn);
    149182       
    150183        /* Quit if the account was locked out. */
     
    165198        NT_STATUS_NOT_OK_RETURN(nt_status);
    166199
     200        if (lm_pwd == NULL && nt_pwd == NULL) {
     201                bool am_rodc;
     202                if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
     203                        /* we don't have passwords for this
     204                         * account. We are an RODC, and this account
     205                         * may be one for which we either are denied
     206                         * REPL_SECRET replication or we haven't yet
     207                         * done the replication. We return
     208                         * NT_STATUS_NOT_IMPLEMENTED which tells the
     209                         * auth code to try the next authentication
     210                         * mechanism. We also send a message to our
     211                         * drepl server to tell it to try and
     212                         * replicate the secrets for this account.
     213                         */
     214                        auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn);
     215                        return NT_STATUS_NOT_IMPLEMENTED;
     216                }
     217        }
     218
    167219        nt_status = authsam_password_ok(auth_context, mem_ctx,
    168220                                        acct_flags, lm_pwd, nt_pwd,
     
    170222        NT_STATUS_NOT_OK_RETURN(nt_status);
    171223
    172         nt_status = authsam_account_ok(mem_ctx, sam_ctx,
     224        nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx,
    173225                                       user_info->logon_parameters,
    174226                                       domain_dn,
     
    186238                                                 TALLOC_CTX *mem_ctx,
    187239                                                 const struct auth_usersupplied_info *user_info,
    188                                                  struct auth_serversupplied_info **server_info)
     240                                                 struct auth_user_info_dc **user_info_dc)
    189241{
    190242        NTSTATUS nt_status;
    191243        const char *account_name = user_info->mapped.account_name;
    192244        struct ldb_message *msg;
    193         struct ldb_context *sam_ctx;
    194245        struct ldb_dn *domain_dn;
    195246        DATA_BLOB user_sess_key, lm_sess_key;
    196247        TALLOC_CTX *tmp_ctx;
    197248
     249        if (ctx->auth_ctx->sam_ctx == NULL) {
     250                DEBUG(0, ("No SAM available, cannot log in users\n"));
     251                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     252        }
     253
    198254        if (!account_name || !*account_name) {
    199255                /* 'not for me' */
     
    206262        }
    207263
    208         sam_ctx = samdb_connect(tmp_ctx, ctx->auth_ctx->event_ctx, ctx->auth_ctx->lp_ctx, system_session(mem_ctx, ctx->auth_ctx->lp_ctx));
    209         if (sam_ctx == NULL) {
    210                 talloc_free(tmp_ctx);
    211                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    212         }
    213 
    214         domain_dn = ldb_get_default_basedn(sam_ctx);
     264        domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
    215265        if (domain_dn == NULL) {
    216266                talloc_free(tmp_ctx);
     
    218268        }
    219269
    220         nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msg);
     270        nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
    221271        if (!NT_STATUS_IS_OK(nt_status)) {
    222272                talloc_free(tmp_ctx);
     
    224274        }
    225275
    226         nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msg, user_info,
     276        nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info,
    227277                                         &user_sess_key, &lm_sess_key);
    228278        if (!NT_STATUS_IS_OK(nt_status)) {
     
    231281        }
    232282
    233         nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
    234                                              lp_sam_name(ctx->auth_ctx->lp_ctx),
     283        nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
     284                                             lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
    235285                                             domain_dn,
    236286                                             msg,
    237287                                             user_sess_key, lm_sess_key,
    238                                              server_info);
     288                                             user_info_dc);
    239289        if (!NT_STATUS_IS_OK(nt_status)) {
    240290                talloc_free(tmp_ctx);
     
    242292        }
    243293
    244         talloc_steal(mem_ctx, *server_info);
     294        talloc_steal(mem_ctx, *user_info_dc);
    245295        talloc_free(tmp_ctx);
    246296
     
    272322        }
    273323
    274         is_local_name = lp_is_myname(ctx->auth_ctx->lp_ctx,
     324        is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx,
    275325                                  user_info->mapped.domain_name);
    276         is_my_domain  = lp_is_mydomain(ctx->auth_ctx->lp_ctx,
     326        is_my_domain  = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx,
    277327                                       user_info->mapped.domain_name);
    278328
    279329        /* check whether or not we service this domain/workgroup name */
    280         switch (lp_server_role(ctx->auth_ctx->lp_ctx)) {
     330        switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
    281331                case ROLE_STANDALONE:
    282332                        return NT_STATUS_OK;
     
    299349        }
    300350
    301         DEBUG(6,("authsam_check_password: lp_server_role() has an undefined value\n"));
     351        DEBUG(6,("authsam_check_password: lpcfg_server_role() has an undefined value\n"));
    302352        return NT_STATUS_NOT_IMPLEMENTED;
    303353}
    304354
    305355                                   
    306 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
    307 NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
    308                                            struct auth_context *auth_context,
    309                                            const char *principal,
    310                                            struct auth_serversupplied_info **server_info)
    311 {
    312         NTSTATUS nt_status;
    313         DATA_BLOB user_sess_key = data_blob(NULL, 0);
    314         DATA_BLOB lm_sess_key = data_blob(NULL, 0);
    315 
    316         struct ldb_message *msg;
    317         struct ldb_context *sam_ctx;
    318         struct ldb_dn *domain_dn;
    319        
    320         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    321         if (!tmp_ctx) {
    322                 return NT_STATUS_NO_MEMORY;
    323         }
    324 
    325         sam_ctx = samdb_connect(tmp_ctx, auth_context->event_ctx, auth_context->lp_ctx,
    326                                 system_session(tmp_ctx, auth_context->lp_ctx));
    327         if (sam_ctx == NULL) {
    328                 talloc_free(tmp_ctx);
    329                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    330         }
    331 
    332         nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
    333                                               user_attrs, &domain_dn, &msg);
    334         if (!NT_STATUS_IS_OK(nt_status)) {
    335                 return nt_status;
    336         }
    337 
    338         nt_status = authsam_make_server_info(tmp_ctx, sam_ctx,
    339                                              lp_netbios_name(auth_context->lp_ctx),
    340                                              lp_workgroup(auth_context->lp_ctx),
    341                                              domain_dn,
    342                                              msg,
    343                                              user_sess_key, lm_sess_key,
    344                                              server_info);
    345         if (NT_STATUS_IS_OK(nt_status)) {
    346                 talloc_steal(mem_ctx, *server_info);
    347         }
    348         talloc_free(tmp_ctx);
    349         return nt_status;
    350 }
    351 
     356/* Wrapper for the auth subsystem pointer */
     357static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
     358                                                          struct auth_context *auth_context,
     359                                                          const char *principal,
     360                                                          struct ldb_dn *user_dn,
     361                                                          struct auth_user_info_dc **user_info_dc)
     362{
     363        return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx,
     364                                                 principal, user_dn, user_info_dc);
     365}
    352366static const struct auth_operations sam_ignoredomain_ops = {
    353367        .name                      = "sam_ignoredomain",
     
    355369        .want_check                = authsam_ignoredomain_want_check,
    356370        .check_password            = authsam_check_password_internals,
    357         .get_server_info_principal = authsam_get_server_info_principal
     371        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
    358372};
    359373
     
    363377        .want_check                = authsam_want_check,
    364378        .check_password            = authsam_check_password_internals,
    365         .get_server_info_principal = authsam_get_server_info_principal
     379        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
    366380};
    367381
  • vendor/current/source4/auth/ntlm/auth_server.c

    r414 r740  
    2222#include "includes.h"
    2323#include "auth/auth.h"
    24 #include "auth/ntlm/auth_proto.h"
    2524#include "auth/credentials/credentials.h"
    2625#include "libcli/security/security.h"
    27 #include "librpc/gen_ndr/ndr_samr.h"
    2826#include "libcli/smb_composite/smb_composite.h"
    2927#include "param/param.h"
     
    4341 * The challenge from the target server, when operating in security=server
    4442 **/
    45 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
     43static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
    4644{
    4745        struct smb_composite_connect io;
     
    5250        /* Make a connection to the target server, found by 'password server' in smb.conf */
    5351       
    54         lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);
     52        lpcfg_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);
    5553
    5654        /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */
     
    5856
    5957        /* Hope we don't get * (the default), as this won't work... */
    60         host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx);
     58        host_list = lpcfg_passwordserver(ctx->auth_ctx->lp_ctx);
    6159        if (!host_list) {
    6260                return NT_STATUS_INTERNAL_ERROR;
     
    6664                return NT_STATUS_INTERNAL_ERROR;
    6765        }
    68         io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx);
    69         io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx);
    70         io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);
     66        io.in.dest_ports = lpcfg_smb_ports(ctx->auth_ctx->lp_ctx);
     67        io.in.socket_options = lpcfg_socket_options(ctx->auth_ctx->lp_ctx);
     68        io.in.gensec_settings = lpcfg_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);
    7169
    7270        io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host);
     
    7573        io.in.credentials = cli_credentials_init_anon(mem_ctx);
    7674        cli_credentials_set_workstation(io.in.credentials,
    77                                         lp_netbios_name(ctx->auth_ctx->lp_ctx),
     75                                        lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
    7876                                        CRED_SPECIFIED);
    7977
     
    8482        io.in.options = smb_options;
    8583       
    86         io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx);
    87         lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);
    88 
    89         status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx),
     84        lpcfg_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);
     85
     86        status = smb_composite_connect(&io, mem_ctx, lpcfg_resolve_context(ctx->auth_ctx->lp_ctx),
    9087                                       ctx->auth_ctx->event_ctx);
    9188        NT_STATUS_NOT_OK_RETURN(status);
    9289
    93         *_blob = io.out.tree->session->transport->negotiate.secblob;
     90        if (io.out.tree->session->transport->negotiate.secblob.length != 8) {
     91                return NT_STATUS_INTERNAL_ERROR;
     92        }
     93        memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8);
    9494        ctx->private_data = talloc_steal(ctx, io.out.tree->session);
    9595        return NT_STATUS_OK;
     
    112112                                      TALLOC_CTX *mem_ctx,
    113113                                      const struct auth_usersupplied_info *user_info,
    114                                       struct auth_serversupplied_info **_server_info)
     114                                      struct auth_user_info_dc **_user_info_dc)
    115115{
    116116        NTSTATUS nt_status;
    117         struct auth_serversupplied_info *server_info;
     117        struct auth_user_info_dc *user_info_dc;
     118        struct auth_user_info *info;
    118119        struct cli_credentials *creds;
    119120        struct smb_composite_sesssetup session_setup;
     
    148149        session_setup.in.credentials = creds;
    149150        session_setup.in.workgroup = ""; /* Only used with SPNEGO, which we are not doing */
    150         session_setup.in.gensec_settings = lp_gensec_settings(session, ctx->auth_ctx->lp_ctx);
     151        session_setup.in.gensec_settings = lpcfg_gensec_settings(session, ctx->auth_ctx->lp_ctx);
    151152
    152153        /* Check password with remove server - this should be async some day */
     
    157158        }
    158159
    159         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    160         NT_STATUS_HAVE_NO_MEMORY(server_info);
    161 
    162         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    163         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    164 
    165         /* is this correct? */
    166         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    167         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    168 
    169         server_info->n_domain_groups = 0;
    170         server_info->domain_groups = NULL;
     160        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     161        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     162
     163        user_info_dc->num_sids = 1;
     164
     165        /* This returns a pointer to a struct dom_sid, which is the
     166         * same as a 1 element list of struct dom_sid */
     167        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
     168        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
    171169
    172170        /* annoying, but the Anonymous really does have a session key,
    173171           and it is all zeros! */
    174         server_info->user_session_key = data_blob(NULL, 0);
    175         server_info->lm_session_key = data_blob(NULL, 0);
    176 
    177         server_info->account_name = talloc_strdup(server_info, user_info->client.account_name);
    178         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    179 
    180         server_info->domain_name = talloc_strdup(server_info, user_info->client.domain_name);
    181         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    182 
    183         server_info->full_name = NULL;
    184 
    185         server_info->logon_script = talloc_strdup(server_info, "");
    186         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    187 
    188         server_info->profile_path = talloc_strdup(server_info, "");
    189         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    190 
    191         server_info->home_directory = talloc_strdup(server_info, "");
    192         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    193 
    194         server_info->home_drive = talloc_strdup(server_info, "");
    195         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    196 
    197         server_info->last_logon = 0;
    198         server_info->last_logoff = 0;
    199         server_info->acct_expiry = 0;
    200         server_info->last_password_change = 0;
    201         server_info->allow_password_change = 0;
    202         server_info->force_password_change = 0;
    203 
    204         server_info->logon_count = 0;
    205         server_info->bad_password_count = 0;
    206 
    207         server_info->acct_flags = ACB_NORMAL;
    208 
    209         server_info->authenticated = false;
    210 
    211         *_server_info = server_info;
     172        user_info_dc->user_session_key = data_blob(NULL, 0);
     173        user_info_dc->lm_session_key = data_blob(NULL, 0);
     174
     175        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     176        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     177
     178        info->account_name = talloc_strdup(user_info_dc, user_info->client.account_name);
     179        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     180
     181        info->domain_name = talloc_strdup(user_info_dc, user_info->client.domain_name);
     182        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     183
     184        info->full_name = NULL;
     185
     186        info->logon_script = talloc_strdup(user_info_dc, "");
     187        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     188
     189        info->profile_path = talloc_strdup(user_info_dc, "");
     190        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     191
     192        info->home_directory = talloc_strdup(user_info_dc, "");
     193        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     194
     195        info->home_drive = talloc_strdup(user_info_dc, "");
     196        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     197
     198        info->last_logon = 0;
     199        info->last_logoff = 0;
     200        info->acct_expiry = 0;
     201        info->last_password_change = 0;
     202        info->allow_password_change = 0;
     203        info->force_password_change = 0;
     204
     205        info->logon_count = 0;
     206        info->bad_password_count = 0;
     207
     208        info->acct_flags = ACB_NORMAL;
     209
     210        info->authenticated = false;
     211
     212        *_user_info_dc = user_info_dc;
    212213
    213214        return nt_status;
  • vendor/current/source4/auth/ntlm/auth_simple.c

    r414 r740  
    2424#include "includes.h"
    2525#include "auth/auth.h"
    26 #include "lib/events/events.h"
    27 #include "param/param.h"
    28 #include "auth/session_proto.h"
    2926
    3027/*
     
    3936                                           const char *nt4_username,
    4037                                           const char *password,
     38                                           const uint32_t logon_parameters,
    4139                                           struct auth_session_info **session_info)
    4240{
    4341        struct auth_context *auth_context;
    4442        struct auth_usersupplied_info *user_info;
    45         struct auth_serversupplied_info *server_info;
     43        struct auth_user_info_dc *user_info_dc;
    4644        NTSTATUS nt_status;
    4745        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     
    6058        }
    6159
    62         user_info = talloc(tmp_ctx, struct auth_usersupplied_info);
     60        user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info);
    6361        if (!user_info) {
    6462                talloc_free(tmp_ctx);
     
    8280                USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
    8381
    84         user_info->logon_parameters = 0;
     82        user_info->logon_parameters = logon_parameters |
     83                MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
     84                MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
    8585
    86         nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info);
     86        nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc);
    8787        if (!NT_STATUS_IS_OK(nt_status)) {
    8888                talloc_free(tmp_ctx);
     
    9191
    9292        if (session_info) {
    93                 nt_status = auth_generate_session_info(tmp_ctx, ev, lp_ctx, server_info, session_info);
     93                uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     94                if (user_info_dc->info->authenticated) {
     95                        flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     96                }
     97                nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
     98                                                                user_info_dc,
     99                                                                flags,
     100                                                                session_info);
    94101
    95102                if (NT_STATUS_IS_OK(nt_status)) {
  • vendor/current/source4/auth/ntlm/auth_unix.c

    r414 r740  
    2424#include "auth/ntlm/auth_proto.h"
    2525#include "system/passwd.h" /* needed by some systems for struct passwd */
    26 #include "lib/socket/socket.h"
    27 #include "auth/ntlm/pam_errors.h"
     26#include "lib/socket/socket.h"
     27#include "lib/tsocket/tsocket.h"
     28#include "../libcli/auth/pam_errors.h"
    2829#include "param/param.h"
    2930
     
    3132 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set
    3233 */
    33 static NTSTATUS authunix_make_server_info(TALLOC_CTX *mem_ctx,
     34static NTSTATUS authunix_make_user_info_dc(TALLOC_CTX *mem_ctx,
    3435                                          const char *netbios_name,
    3536                                          const struct auth_usersupplied_info *user_info,
    3637                                          struct passwd *pwd,
    37                                           struct auth_serversupplied_info **_server_info)
    38 {
    39         struct auth_serversupplied_info *server_info;
     38                                          struct auth_user_info_dc **_user_info_dc)
     39{
     40        struct auth_user_info_dc *user_info_dc;
     41        struct auth_user_info *info;
    4042        NTSTATUS status;
    4143
    4244        /* This is a real, real hack */
    4345        if (pwd->pw_uid == 0) {
    44                 status = auth_system_server_info(mem_ctx, netbios_name, &server_info);
     46                status = auth_system_user_info_dc(mem_ctx, netbios_name, &user_info_dc);
    4547                if (!NT_STATUS_IS_OK(status)) {
    4648                        return status;
    4749                }
    4850
    49                 server_info->account_name = talloc_steal(server_info, pwd->pw_name);
    50                 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
     51                user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     52                NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     53
     54                info->account_name = talloc_steal(info, pwd->pw_name);
     55                NT_STATUS_HAVE_NO_MEMORY(info->account_name);
    5156               
    52                 server_info->domain_name = talloc_strdup(server_info, "unix");
    53                 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
     57                info->domain_name = talloc_strdup(info, "unix");
     58                NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
    5459        } else {
    55                 server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    56                 NT_STATUS_HAVE_NO_MEMORY(server_info);
     60                user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     61                NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
    5762               
    58                 server_info->authenticated = true;
     63                user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     64                NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     65
     66                info->authenticated = true;
    5967               
    60                 server_info->account_name = talloc_steal(server_info, pwd->pw_name);
    61                 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
     68                info->account_name = talloc_steal(info, pwd->pw_name);
     69                NT_STATUS_HAVE_NO_MEMORY(info->account_name);
    6270               
    63                 server_info->domain_name = talloc_strdup(server_info, "unix");
    64                 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
     71                info->domain_name = talloc_strdup(info, "unix");
     72                NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
    6573
    6674                /* This isn't in any way correct.. */
    67                 server_info->account_sid = NULL;
    68                 server_info->primary_group_sid = NULL;
    69                 server_info->n_domain_groups = 0;
    70                 server_info->domain_groups = NULL;
    71         }
    72         server_info->user_session_key = data_blob(NULL,0);
    73         server_info->lm_session_key = data_blob(NULL,0);
    74 
    75         server_info->full_name = talloc_steal(server_info, pwd->pw_gecos);
    76         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    77         server_info->logon_script = talloc_strdup(server_info, "");
    78         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    79         server_info->profile_path = talloc_strdup(server_info, "");
    80         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    81         server_info->home_directory = talloc_strdup(server_info, "");
    82         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    83         server_info->home_drive = talloc_strdup(server_info, "");
    84         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    85 
    86         server_info->last_logon = 0;
    87         server_info->last_logoff = 0;
    88         server_info->acct_expiry = 0;
    89         server_info->last_password_change = 0;
    90         server_info->allow_password_change = 0;
    91         server_info->force_password_change = 0;
    92         server_info->logon_count = 0;
    93         server_info->bad_password_count = 0;
    94         server_info->acct_flags = 0;
    95 
    96         *_server_info = server_info;
     75                user_info_dc->num_sids = 0;
     76                user_info_dc->sids = NULL;
     77        }
     78        user_info_dc->user_session_key = data_blob(NULL,0);
     79        user_info_dc->lm_session_key = data_blob(NULL,0);
     80
     81        info->full_name = talloc_steal(info, pwd->pw_gecos);
     82        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     83        info->logon_script = talloc_strdup(info, "");
     84        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     85        info->profile_path = talloc_strdup(info, "");
     86        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     87        info->home_directory = talloc_strdup(info, "");
     88        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     89        info->home_drive = talloc_strdup(info, "");
     90        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     91
     92        info->last_logon = 0;
     93        info->last_logoff = 0;
     94        info->acct_expiry = 0;
     95        info->last_password_change = 0;
     96        info->allow_password_change = 0;
     97        info->force_password_change = 0;
     98        info->logon_count = 0;
     99        info->bad_password_count = 0;
     100        info->acct_flags = 0;
     101
     102        *_user_info_dc = user_info_dc;
    97103
    98104        return NT_STATUS_OK;
     
    430436}
    431437
    432 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 
     438static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
    433439                                    const struct auth_usersupplied_info *user_info, struct passwd **pws)
    434440{
     
    459465         */
    460466
    461         nt_status = smb_pam_start(&pamh, user_info->mapped.account_name, user_info->remote_host ? user_info->remote_host->addr : NULL, pamconv);
     467        nt_status = smb_pam_start(&pamh, user_info->mapped.account_name,
     468                        user_info->remote_host ? tsocket_address_inet_addr_string(user_info->remote_host, ctx) : NULL, pamconv);
    462469        if (!NT_STATUS_IS_OK(nt_status)) {
    463470                return nt_status;
    464471        }
    465472
    466         nt_status = smb_pam_auth(pamh, lp_null_passwords(lp_ctx), user_info->mapped.account_name);
     473        nt_status = smb_pam_auth(pamh, lpcfg_null_passwords(lp_ctx), user_info->mapped.account_name);
    467474        if (!NT_STATUS_IS_OK(nt_status)) {
    468475                smb_pam_end(pamh);
     
    604611        struct passwd *pws;
    605612        NTSTATUS nt_status;
    606         int level = lp_passwordlevel(lp_ctx);
     613        int level = lpcfg_passwordlevel(lp_ctx);
    607614
    608615        *ret_passwd = NULL;
     
    707714
    708715        if (crypted[0] == '\0') {
    709                 if (!lp_null_passwords(lp_ctx)) {
     716                if (!lpcfg_null_passwords(lp_ctx)) {
    710717                        DEBUG(2, ("Disallowing %s with null password\n", username));
    711718                        return NT_STATUS_LOGON_FAILURE;
     
    792799                                        TALLOC_CTX *mem_ctx,
    793800                                        const struct auth_usersupplied_info *user_info,
    794                                         struct auth_serversupplied_info **server_info)
     801                                        struct auth_user_info_dc **user_info_dc)
    795802{
    796803        TALLOC_CTX *check_ctx;
     
    813820        }
    814821
    815         nt_status = authunix_make_server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
    816                                               user_info, pwd, server_info);
     822        nt_status = authunix_make_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
     823                                              user_info, pwd, user_info_dc);
    817824        if (!NT_STATUS_IS_OK(nt_status)) {
    818825                talloc_free(check_ctx);
  • vendor/current/source4/auth/ntlm/auth_util.c

    r414 r740  
    2424#include "includes.h"
    2525#include "auth/auth.h"
    26 #include "auth/auth_proto.h"
    27 #include "libcli/security/security.h"
    2826#include "libcli/auth/libcli_auth.h"
    29 #include "dsdb/samdb/samdb.h"
    30 #include "auth/credentials/credentials.h"
    3127#include "param/param.h"
    3228
     
    3430 * which don't want to set a challenge
    3531 */
    36 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge)
     32NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
    3733{
    3834        /* we don't want to set a challenge */
     
    7975        }
    8076
    81         *user_info_mapped = talloc(mem_ctx, struct auth_usersupplied_info);
     77        *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    8278        if (!*user_info_mapped) {
    8379                return NT_STATUS_NO_MEMORY;
     
    127123                case AUTH_PASSWORD_HASH:
    128124                {
    129                         const uint8_t *challenge;
     125                        uint8_t chal[8];
    130126                        DATA_BLOB chall_blob;
    131                         user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info);
     127                        user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    132128                        if (!user_info_temp) {
    133129                                return NT_STATUS_NO_MEMORY;
     
    139135                        user_info_temp->mapped_state = to_state;
    140136                       
    141                         nt_status = auth_get_challenge(auth_context, &challenge);
     137                        nt_status = auth_get_challenge(auth_context, chal);
    142138                        if (!NT_STATUS_IS_OK(nt_status)) {
    143139                                return nt_status;
    144140                        }
    145141                       
    146                         chall_blob = data_blob_talloc(mem_ctx, challenge, 8);
    147                         if (lp_client_ntlmv2_auth(auth_context->lp_ctx)) {
    148                                 DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lp_netbios_name(auth_context->lp_ctx), lp_workgroup(auth_context->lp_ctx));
     142                        chall_blob = data_blob_talloc(mem_ctx, chal, 8);
     143                        if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) {
     144                                DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx));
    149145                                DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key;
    150146                               
     
    167163                        } else {
    168164                                DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
    169                                 SMBOWFencrypt(user_info_in->password.hash.nt->hash, challenge, blob.data);
     165                                SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data);
    170166
    171167                                user_info_temp->password.response.nt = blob;
    172                                 if (lp_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
     168                                if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
    173169                                        DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24);
    174                                         SMBOWFencrypt(user_info_in->password.hash.lanman->hash, challenge, blob.data);
     170                                        SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data);
    175171                                        user_info_temp->password.response.lanman = lm_blob;
    176172                                } else {
     
    195191                        struct samr_Password nt;
    196192                       
    197                         user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info);
     193                        user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    198194                        if (!user_info_temp) {
    199195                                return NT_STATUS_NO_MEMORY;
     
    236232        return NT_STATUS_OK;
    237233}
    238 
    239 
    240 /**
    241  * Squash an NT_STATUS in line with security requirements.
    242  * In an attempt to avoid giving the whole game away when users
    243  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
    244  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
    245  * (session setups in particular).
    246  *
    247  * @param nt_status NTSTATUS input for squashing.
    248  * @return the 'squashed' nt_status
    249  **/
    250 _PUBLIC_ NTSTATUS auth_nt_status_squash(NTSTATUS nt_status)
    251 {
    252         if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
    253                 /* Match WinXP and don't give the game away */
    254                 return NT_STATUS_LOGON_FAILURE;
    255         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
    256                 /* Match WinXP and don't give the game away */
    257                 return NT_STATUS_LOGON_FAILURE;
    258         }
    259 
    260         return nt_status;
    261 }
  • vendor/current/source4/auth/ntlm/auth_winbind.c

    r414 r740  
    2626#include "auth/ntlm/auth_proto.h"
    2727#include "auth/auth_sam_reply.h"
    28 #include "nsswitch/winbind_client.h"
    29 #include "librpc/gen_ndr/ndr_netlogon.h"
    30 #include "librpc/gen_ndr/ndr_winbind.h"
     28#include "librpc/gen_ndr/ndr_winbind_c.h"
    3129#include "lib/messaging/irpc.h"
    3230#include "param/param.h"
    3331#include "nsswitch/libwbclient/wbclient.h"
    34 #include "libcli/security/dom_sid.h"
    35 
    36 static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, struct winbindd_response *response, struct netr_SamInfo3 *info3)
    37 {
    38         size_t len = response->length - sizeof(struct winbindd_response);
    39         if (len > 4) {
    40                 enum ndr_err_code ndr_err;
    41                 DATA_BLOB blob;
    42                 blob.length = len - 4;
    43                 blob.data = (uint8_t *)(((char *)response->extra_data.data) + 4);
    44 
    45                 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx,
    46                                iconv_convenience, info3,
    47                               (ndr_pull_flags_fn_t)ndr_pull_netr_SamInfo3);
    48                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    49                         return ndr_map_error2ntstatus(ndr_err);
    50                 }
    51 
    52                 return NT_STATUS_OK;
    53         } else {
    54                 DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
    55                 return NT_STATUS_UNSUCCESSFUL;
    56         }
    57 }
     32#include "libcli/security/security.h"
    5833
    5934static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
    60                                                struct smb_iconv_convenience *ic,
    6135                                               struct wbcAuthUserInfo *info,
    6236                                               struct netr_SamInfo3 *info3)
     
    6438        int i, j;
    6539        struct samr_RidWithAttribute *rids = NULL;
     40        struct dom_sid *user_sid;
     41        struct dom_sid *group_sid;
     42
     43        user_sid = (struct dom_sid *)(void *)&info->sids[0].sid;
     44        group_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
    6645
    6746        info3->base.last_logon = info->logon_time;
     
    10382        }
    10483
    105         dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[0].sid,
     84        dom_sid_split_rid(mem_ctx, user_sid,
    10685                          &info3->base.domain_sid,
    10786                          &info3->base.rid);
    108         dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[1].sid, NULL,
     87        dom_sid_split_rid(mem_ctx, group_sid, NULL,
    10988                          &info3->base.primary_gid);
    11089
     
    11796
    11897        for (i = 2, j = 0; i < info->num_sids; ++i, ++j) {
     98                struct dom_sid *tmp_sid;
     99                tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
     100
    119101                rids[j].attributes = info->sids[i].attributes;
    120                 dom_sid_split_rid(mem_ctx,
    121                                   (struct dom_sid2 *) &info->sids[i].sid,
     102                dom_sid_split_rid(mem_ctx, tmp_sid,
    122103                                  NULL, &rids[j].rid);
    123104        }
     
    138119        /* TODO: maybe limit the user scope to remote users only */
    139120        return NT_STATUS_OK;
    140 }
    141 
    142 /*
    143  Authenticate a user with a challenge/response
    144  using the samba3 winbind protocol
    145 */
    146 static NTSTATUS winbind_check_password_samba3(struct auth_method_context *ctx,
    147                                               TALLOC_CTX *mem_ctx,
    148                                               const struct auth_usersupplied_info *user_info,
    149                                               struct auth_serversupplied_info **server_info)
    150 {
    151         struct winbindd_request request;
    152         struct winbindd_response response;
    153         NSS_STATUS result;
    154         NTSTATUS nt_status;
    155         struct netr_SamInfo3 info3;             
    156 
    157         /* Send off request */
    158         const struct auth_usersupplied_info *user_info_temp;   
    159         nt_status = encrypt_user_info(mem_ctx, ctx->auth_ctx,
    160                                       AUTH_PASSWORD_RESPONSE,
    161                                       user_info, &user_info_temp);
    162         if (!NT_STATUS_IS_OK(nt_status)) {
    163                 return nt_status;
    164         }
    165         user_info = user_info_temp;
    166 
    167         ZERO_STRUCT(request);
    168         ZERO_STRUCT(response);
    169         request.flags = WBFLAG_PAM_INFO3_NDR;
    170 
    171         request.data.auth_crap.logon_parameters = user_info->logon_parameters;
    172 
    173         safe_strcpy(request.data.auth_crap.user,
    174                        user_info->client.account_name, sizeof(fstring));
    175         safe_strcpy(request.data.auth_crap.domain,
    176                        user_info->client.domain_name, sizeof(fstring));
    177         safe_strcpy(request.data.auth_crap.workstation,
    178                        user_info->workstation_name, sizeof(fstring));
    179 
    180         memcpy(request.data.auth_crap.chal, ctx->auth_ctx->challenge.data.data, sizeof(request.data.auth_crap.chal));
    181 
    182         request.data.auth_crap.lm_resp_len = MIN(user_info->password.response.lanman.length,
    183                                                  sizeof(request.data.auth_crap.lm_resp));
    184         request.data.auth_crap.nt_resp_len = MIN(user_info->password.response.nt.length,
    185                                                  sizeof(request.data.auth_crap.nt_resp));
    186 
    187         memcpy(request.data.auth_crap.lm_resp, user_info->password.response.lanman.data,
    188                request.data.auth_crap.lm_resp_len);
    189         memcpy(request.data.auth_crap.nt_resp, user_info->password.response.nt.data,
    190                request.data.auth_crap.nt_resp_len);
    191 
    192         result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
    193 
    194         nt_status = NT_STATUS(response.data.auth.nt_status);
    195         NT_STATUS_NOT_OK_RETURN(nt_status);
    196 
    197         if (result == NSS_STATUS_SUCCESS && response.extra_data.data) {
    198                 union netr_Validation validation;
    199 
    200                 nt_status = get_info3_from_ndr(mem_ctx, lp_iconv_convenience(ctx->auth_ctx->lp_ctx), &response, &info3);
    201                 SAFE_FREE(response.extra_data.data);
    202                 NT_STATUS_NOT_OK_RETURN(nt_status);
    203 
    204                 validation.sam3 = &info3;
    205                 nt_status = make_server_info_netlogon_validation(mem_ctx,
    206                                                                  user_info->client.account_name,
    207                                                                  3, &validation,
    208                                                                  server_info);
    209                 return nt_status;
    210         } else if (result == NSS_STATUS_SUCCESS && !response.extra_data.data) {
    211                 DEBUG(0, ("Winbindd authenticated the user [%s]\\[%s], "
    212                           "but did not include the required info3 reply!\n",
    213                           user_info->client.domain_name, user_info->client.account_name));
    214                 return NT_STATUS_INSUFFICIENT_LOGON_INFO;
    215         } else if (NT_STATUS_IS_OK(nt_status)) {
    216                 DEBUG(1, ("Winbindd authentication for [%s]\\[%s] failed, "
    217                           "but no error code is available!\n",
    218                           user_info->client.domain_name, user_info->client.account_name));
    219                 return NT_STATUS_NO_LOGON_SERVERS;
    220         }
    221 
    222         return nt_status;
    223121}
    224122
     
    234132                                       TALLOC_CTX *mem_ctx,
    235133                                       const struct auth_usersupplied_info *user_info,
    236                                        struct auth_serversupplied_info **server_info)
     134                                       struct auth_user_info_dc **user_info_dc)
    237135{
    238136        NTSTATUS status;
    239         struct server_id *winbind_servers;
     137        struct dcerpc_binding_handle *irpc_handle;
    240138        struct winbind_check_password_state *s;
    241139        const struct auth_usersupplied_info *user_info_new;
    242140        struct netr_IdentityInfo *identity_info;
    243141
     142        if (!ctx->auth_ctx->msg_ctx) {
     143                DEBUG(0,("winbind_check_password: auth_context_create was called with out messaging context\n"));
     144                return NT_STATUS_INTERNAL_ERROR;
     145        }
     146
    244147        s = talloc(mem_ctx, struct winbind_check_password_state);
    245148        NT_STATUS_HAVE_NO_MEMORY(s);
    246149
    247         winbind_servers = irpc_servers_byname(ctx->auth_ctx->msg_ctx, s, "winbind_server");
    248         if ((winbind_servers == NULL) || (winbind_servers[0].id == 0)) {
     150        irpc_handle = irpc_binding_handle_by_name(s, ctx->auth_ctx->msg_ctx,
     151                                                  "winbind_server",
     152                                                  &ndr_table_winbind);
     153        if (irpc_handle == NULL) {
    249154                DEBUG(0, ("Winbind authentication for [%s]\\[%s] failed, "
    250155                          "no winbind_server running!\n",
     
    272177        } else {
    273178                struct netr_NetworkInfo *network_info;
    274                 const uint8_t *challenge;
     179                uint8_t chal[8];
    275180
    276181                status = encrypt_user_info(s, ctx->auth_ctx, AUTH_PASSWORD_RESPONSE,
     
    282187                NT_STATUS_HAVE_NO_MEMORY(network_info);
    283188
    284                 status = auth_get_challenge(ctx->auth_ctx, &challenge);
     189                status = auth_get_challenge(ctx->auth_ctx, chal);
    285190                NT_STATUS_NOT_OK_RETURN(status);
    286191
    287                 memcpy(network_info->challenge, challenge, sizeof(network_info->challenge));
     192                memcpy(network_info->challenge, chal, sizeof(network_info->challenge));
    288193
    289194                network_info->nt.length = user_info->password.response.nt.length;
     
    307212        s->req.in.validation_level      = 3;
    308213
    309         status = IRPC_CALL(ctx->auth_ctx->msg_ctx, winbind_servers[0],
    310                            winbind, WINBIND_SAMLOGON,
    311                            &s->req, s);
     214        status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req);
    312215        NT_STATUS_NOT_OK_RETURN(status);
    313216
    314         status = make_server_info_netlogon_validation(mem_ctx,
     217        status = make_user_info_dc_netlogon_validation(mem_ctx,
    315218                                                      user_info->client.account_name,
    316219                                                      s->req.in.validation_level,
    317220                                                      &s->req.out.validation,
    318                                                       server_info);
     221                                                      user_info_dc);
    319222        NT_STATUS_NOT_OK_RETURN(status);
    320223
     
    329232                                                TALLOC_CTX *mem_ctx,
    330233                                                const struct auth_usersupplied_info *user_info,
    331                                                 struct auth_serversupplied_info **server_info)
     234                                                struct auth_user_info_dc **user_info_dc)
    332235{
    333236        struct wbcAuthUserParams params;
     
    382285
    383286        wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
    384         if (!WBC_ERROR_IS_OK(wbc_status)) {
     287        if (wbc_status == WBC_ERR_AUTH_ERROR) {
    385288                DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
    386289                      err->nt_string, err->nt_status, err->display_string));
     
    389292                wbcFreeMemory(err);
    390293                NT_STATUS_NOT_OK_RETURN(nt_status);
    391         }
    392         nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx,
    393                                 lp_iconv_convenience(ctx->auth_ctx->lp_ctx),
    394                                 info, &info3);
     294        } else if (!WBC_ERROR_IS_OK(wbc_status)) {
     295                DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n",
     296                        wbc_status, wbcErrorString(wbc_status)));
     297                return NT_STATUS_LOGON_FAILURE;
     298        }
     299        nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3);
    395300        wbcFreeMemory(info);
    396301        NT_STATUS_NOT_OK_RETURN(nt_status);
    397302
    398303        validation.sam3 = &info3;
    399         nt_status = make_server_info_netlogon_validation(mem_ctx,
     304        nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    400305                                        user_info->client.account_name,
    401                                         3, &validation, server_info);
     306                                        3, &validation, user_info_dc);
    402307        return nt_status;
    403308
    404309}
    405 
    406 static const struct auth_operations winbind_samba3_ops = {
    407         .name           = "winbind_samba3",
    408         .get_challenge  = auth_get_challenge_not_implemented,
    409         .want_check     = winbind_want_check,
    410         .check_password = winbind_check_password_samba3
    411 };
    412310
    413311static const struct auth_operations winbind_ops = {
     
    429327        NTSTATUS ret;
    430328
    431         ret = auth_register(&winbind_samba3_ops);
    432         if (!NT_STATUS_IS_OK(ret)) {
    433                 DEBUG(0,("Failed to register 'winbind_samba3' auth backend!\n"));
    434                 return ret;
    435         }
    436 
    437329        ret = auth_register(&winbind_ops);
    438330        if (!NT_STATUS_IS_OK(ret)) {
  • vendor/current/source4/auth/ntlmssp/ntlmssp.c

    r414 r740  
    2424#include "includes.h"
    2525#include "auth/ntlmssp/ntlmssp.h"
    26 #include "../librpc/gen_ndr/ntlmssp.h"
    2726#include "../libcli/auth/libcli_auth.h"
    2827#include "librpc/gen_ndr/ndr_dcerpc.h"
    29 #include "auth/credentials/credentials.h"
    3028#include "auth/gensec/gensec.h"
    3129#include "auth/gensec/gensec_proto.h"
    32 #include "param/param.h"
    3330
    3431/**
     
    5148                .role           = NTLMSSP_SERVER,
    5249                .command        = NTLMSSP_NEGOTIATE,
    53                 .sync_fn        = ntlmssp_server_negotiate,
     50                .sync_fn        = gensec_ntlmssp_server_negotiate,
    5451        },{
    5552                .role           = NTLMSSP_CLIENT,
     
    5956                .role           = NTLMSSP_SERVER,
    6057                .command        = NTLMSSP_AUTH,
    61                 .sync_fn        = ntlmssp_server_auth,
     58                .sync_fn        = gensec_ntlmssp_server_auth,
    6259        }
    6360};
    6461
    65 
    66 /**
    67  * Print out the NTLMSSP flags for debugging
    68  * @param neg_flags The flags from the packet
    69  */
    70 
    71 void debug_ntlmssp_flags(uint32_t neg_flags)
    72 {
    73         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
    74        
    75         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
    76                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
    77         if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
    78                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
    79         if (neg_flags & NTLMSSP_REQUEST_TARGET)
    80                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
    81         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
    82                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
    83         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
    84                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
    85         if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)
    86                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM\n"));
    87         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    88                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
    89         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
    90                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
    91         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
    92                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
    93         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)
    94                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));
    95         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)
    96                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));
    97         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
    98                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
    99         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
    100                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
    101         if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)
    102                 DEBUGADD(4, ("  NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));
    103         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
    104                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
    105         if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)
    106                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_TARGET_INFO\n"));
    107         if (neg_flags & NTLMSSP_NEGOTIATE_128)
    108                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
    109         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
    110                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
    111         if (neg_flags & NTLMSSP_NEGOTIATE_56)
    112                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
    113 }
    11462
    11563static NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security,
     
    12371}
    12472
    125 static NTSTATUS gensec_ntlmssp_update_find(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
     73static NTSTATUS gensec_ntlmssp_update_find(struct ntlmssp_state *ntlmssp_state,
    12674                                           const DATA_BLOB input, uint32_t *idx)
    12775{
    128         struct gensec_security *gensec_security = gensec_ntlmssp_state->gensec_security;
     76        struct gensec_ntlmssp_context *gensec_ntlmssp =
     77                talloc_get_type_abort(ntlmssp_state->callback_private,
     78                                      struct gensec_ntlmssp_context);
     79        struct gensec_security *gensec_security = gensec_ntlmssp->gensec_security;
    12980        uint32_t ntlmssp_command;
    13081        uint32_t i;
    13182
    132         if (gensec_ntlmssp_state->expected_state == NTLMSSP_DONE) {
     83        if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
    13384                /* We are strict here because other modules, which we
    13485                 * don't fully control (such as GSSAPI) are also
     
    14091
    14192        if (!input.length) {
    142                 switch (gensec_ntlmssp_state->role) {
     93                switch (ntlmssp_state->role) {
    14394                case NTLMSSP_CLIENT:
    14495                        ntlmssp_command = NTLMSSP_INITIAL;
     
    156107                }
    157108        } else {
    158                 if (!msrpc_parse(gensec_ntlmssp_state,
     109                if (!msrpc_parse(ntlmssp_state,
    159110                                 &input, "Cd",
    160111                                 "NTLMSSP",
     
    166117        }
    167118
    168         if (ntlmssp_command != gensec_ntlmssp_state->expected_state) {
    169                 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, gensec_ntlmssp_state->expected_state));
     119        if (ntlmssp_command != ntlmssp_state->expected_state) {
     120                DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
    170121                return NT_STATUS_INVALID_PARAMETER;
    171122        }
    172123
    173124        for (i=0; i < ARRAY_SIZE(ntlmssp_callbacks); i++) {
    174                 if (ntlmssp_callbacks[i].role == gensec_ntlmssp_state->role &&
     125                if (ntlmssp_callbacks[i].role == ntlmssp_state->role &&
    175126                    ntlmssp_callbacks[i].command == ntlmssp_command) {
    176127                        *idx = i;
     
    180131
    181132        DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
    182                   gensec_ntlmssp_state->role, ntlmssp_command));
     133                  ntlmssp_state->role, ntlmssp_command));
    183134               
    184135        return NT_STATUS_INVALID_PARAMETER;
     
    200151                                      const DATA_BLOB input, DATA_BLOB *out)
    201152{
    202         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     153        struct gensec_ntlmssp_context *gensec_ntlmssp =
     154                talloc_get_type_abort(gensec_security->private_data,
     155                                      struct gensec_ntlmssp_context);
     156        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
    203157        NTSTATUS status;
    204158        uint32_t i;
     
    209163                /* if the caller doesn't want to manage/own the memory,
    210164                   we can put it on our context */
    211                 out_mem_ctx = gensec_ntlmssp_state;
    212         }
    213 
    214         status = gensec_ntlmssp_update_find(gensec_ntlmssp_state, input, &i);
     165                out_mem_ctx = ntlmssp_state;
     166        }
     167
     168        status = gensec_ntlmssp_update_find(ntlmssp_state, input, &i);
    215169        NT_STATUS_NOT_OK_RETURN(status);
    216170
     
    224178 * Return the NTLMSSP master session key
    225179 *
    226  * @param gensec_ntlmssp_state NTLMSSP State
     180 * @param ntlmssp_state NTLMSSP State
    227181 */
    228182
     
    230184                                    DATA_BLOB *session_key)
    231185{
    232         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    233 
    234         if (gensec_ntlmssp_state->expected_state != NTLMSSP_DONE) {
     186        struct gensec_ntlmssp_context *gensec_ntlmssp =
     187                talloc_get_type_abort(gensec_security->private_data,
     188                                      struct gensec_ntlmssp_context);
     189        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     190
     191        if (ntlmssp_state->expected_state != NTLMSSP_DONE) {
    235192                return NT_STATUS_NO_USER_SESSION_KEY;
    236193        }
    237194
    238         if (!gensec_ntlmssp_state->session_key.data) {
     195        if (!ntlmssp_state->session_key.data) {
    239196                return NT_STATUS_NO_USER_SESSION_KEY;
    240197        }
    241         *session_key = gensec_ntlmssp_state->session_key;
     198        *session_key = ntlmssp_state->session_key;
    242199
    243200        return NT_STATUS_OK;
    244 }
    245 
    246 void ntlmssp_handle_neg_flags(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    247                               uint32_t neg_flags, bool allow_lm)
    248 {
    249         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
    250                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
    251                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
    252                 gensec_ntlmssp_state->unicode = true;
    253         } else {
    254                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
    255                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
    256                 gensec_ntlmssp_state->unicode = false;
    257         }
    258 
    259         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !gensec_ntlmssp_state->use_ntlmv2) {
    260                 /* other end forcing us to use LM */
    261                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
    262                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    263         } else {
    264                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    265         }
    266 
    267         if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
    268                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    269         }
    270 
    271         if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
    272                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
    273         }
    274 
    275         if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
    276                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
    277         }
    278 
    279         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
    280                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    281         }
    282 
    283         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
    284                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
    285         }
    286 
    287         if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
    288                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
    289         }
    290 
    291         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
    292                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
    293         }
    294 
    295         /* Woop Woop - unknown flag for Windows compatibility...
    296            What does this really do ? JRA. */
    297         if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {
    298                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;
    299         }
    300 
    301         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
    302                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
    303         }
    304        
    305 }
    306 
    307 /**
    308    Weaken NTLMSSP keys to cope with down-level clients and servers.
    309 
    310    We probably should have some parameters to control this, but as
    311    it only occours for LM_KEY connections, and this is controlled
    312    by the client lanman auth/lanman auth parameters, it isn't too bad.
    313 */
    314 
    315 DATA_BLOB ntlmssp_weakend_key(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    316                               TALLOC_CTX *mem_ctx)
    317 {
    318         DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
    319                                                   gensec_ntlmssp_state->session_key.data,
    320                                                   gensec_ntlmssp_state->session_key.length);
    321         /* Nothing to weaken.  We certainly don't want to 'extend' the length... */
    322         if (weakened_key.length < 16) {
    323                 /* perhaps there was no key? */
    324                 return weakened_key;
    325         }
    326 
    327         /* Key weakening not performed on the master key for NTLM2
    328            and does not occour for NTLM1.  Therefore we only need
    329            to do this for the LM_KEY. 
    330         */
    331         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
    332                 /* LM key doesn't support 128 bit crypto, so this is
    333                  * the best we can do.  If you negotiate 128 bit, but
    334                  * not 56, you end up with 40 bit... */
    335                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
    336                         weakened_key.data[7] = 0xa0;
    337                         weakened_key.length = 8;
    338                 } else { /* forty bits */
    339                         weakened_key.data[5] = 0xe5;
    340                         weakened_key.data[6] = 0x38;
    341                         weakened_key.data[7] = 0xb0;
    342                         weakened_key.length = 8;
    343                 }
    344         }
    345         return weakened_key;
    346201}
    347202
     
    349204                                        uint32_t feature)
    350205{
    351         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     206        struct gensec_ntlmssp_context *gensec_ntlmssp =
     207                talloc_get_type_abort(gensec_security->private_data,
     208                                      struct gensec_ntlmssp_context);
     209        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     210
    352211        if (feature & GENSEC_FEATURE_SIGN) {
    353                 if (!gensec_ntlmssp_state->session_key.length) {
     212                if (!ntlmssp_state->session_key.length) {
    354213                        return false;
    355214                }
    356                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
     215                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
    357216                        return true;
    358217                }
    359218        }
    360219        if (feature & GENSEC_FEATURE_SEAL) {
    361                 if (!gensec_ntlmssp_state->session_key.length) {
     220                if (!ntlmssp_state->session_key.length) {
    362221                        return false;
    363222                }
    364                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
     223                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
    365224                        return true;
    366225                }
    367226        }
    368227        if (feature & GENSEC_FEATURE_SESSION_KEY) {
    369                 if (gensec_ntlmssp_state->session_key.length) {
     228                if (ntlmssp_state->session_key.length) {
    370229                        return true;
    371230                }
     
    375234        }
    376235        if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
    377                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     236                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    378237                        return true;
    379238                }
     
    384243NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security)
    385244{
    386         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
    387        
    388         gensec_ntlmssp_state = talloc_zero(gensec_security, struct gensec_ntlmssp_state);
    389         if (!gensec_ntlmssp_state) {
     245        struct gensec_ntlmssp_context *gensec_ntlmssp;
     246        struct ntlmssp_state *ntlmssp_state;
     247
     248        gensec_ntlmssp = talloc_zero(gensec_security,
     249                                     struct gensec_ntlmssp_context);
     250        if (!gensec_ntlmssp) {
    390251                return NT_STATUS_NO_MEMORY;
    391252        }
    392253
    393         gensec_ntlmssp_state->gensec_security = gensec_security;
    394         gensec_ntlmssp_state->auth_context = NULL;
    395         gensec_ntlmssp_state->server_info = NULL;
    396 
    397         gensec_security->private_data = gensec_ntlmssp_state;
     254        gensec_ntlmssp->gensec_security = gensec_security;
     255
     256        ntlmssp_state = talloc_zero(gensec_ntlmssp,
     257                                    struct ntlmssp_state);
     258        if (!ntlmssp_state) {
     259                return NT_STATUS_NO_MEMORY;
     260        }
     261
     262        ntlmssp_state->callback_private = gensec_ntlmssp;
     263
     264        gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
     265
     266        gensec_security->private_data = gensec_ntlmssp;
    398267        return NT_STATUS_OK;
    399268}
     
    406275static const struct gensec_security_ops gensec_ntlmssp_security_ops = {
    407276        .name           = "ntlmssp",
    408         .sasl_name      = "NTLM",
     277        .sasl_name      = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */
    409278        .auth_type      = DCERPC_AUTH_TYPE_NTLMSSP,
    410279        .oid            = gensec_ntlmssp_oids,
  • vendor/current/source4/auth/ntlmssp/ntlmssp.h

    r414 r740  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   SMB parameters and setup
     
    55   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    66   Copyright (C) Paul Ashton 1997
    7    
     7   Copyright (C) Andrew Bartlett 2010
     8
    89   This program is free software; you can redistribute it and/or modify
    910   it under the terms of the GNU General Public License as published by
    1011   the Free Software Foundation; either version 3 of the License, or
    1112   (at your option) any later version.
    12    
     13
    1314   This program is distributed in the hope that it will be useful,
    1415   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1516   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1617   GNU General Public License for more details.
    17    
     18
    1819   You should have received a copy of the GNU General Public License
    1920   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    2021*/
    2122
    22 #include "librpc/gen_ndr/samr.h"
    2323#include "../librpc/gen_ndr/ntlmssp.h"
     24#include "../libcli/auth/ntlmssp.h"
    2425
    25 /* NTLMSSP mode */
    26 enum ntlmssp_role
    27 {
    28         NTLMSSP_SERVER,
    29         NTLMSSP_CLIENT
    30 };
    31 
    32 /* NTLMSSP message types */
    33 enum ntlmssp_message_type
    34 {
    35         NTLMSSP_INITIAL = 0 /* samba internal state */,
    36         NTLMSSP_NEGOTIATE = 1,
    37         NTLMSSP_CHALLENGE = 2,
    38         NTLMSSP_AUTH      = 3,
    39         NTLMSSP_UNKNOWN   = 4,
    40         NTLMSSP_DONE   = 5 /* samba final state */
    41 };
    42 
    43 struct gensec_ntlmssp_state
    44 {
     26struct gensec_ntlmssp_context {
    4527        struct gensec_security *gensec_security;
    46 
    47         enum ntlmssp_role role;
    48         enum samr_Role server_role;
    49         uint32_t expected_state;
    50 
    51         bool unicode;
    52         bool use_ntlmv2;
    53         bool use_nt_response;  /* Set to 'False' to debug what happens when the NT response is omited */
    54         bool allow_lm_key;     /* The LM_KEY code is not functional at this point, and it's not
    55                                   very secure anyway */
    56 
    57         bool server_multiple_authentications;  /* Set to 'True' to allow squid 2.5
    58                                                   style 'challenge caching' */
    59 
    60         char *user;
    61         const char *domain;
    62         const char *workstation;
    63         char *server_domain;
    64 
    65         DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */
    66 
    67         DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */
    68         DATA_BLOB lm_resp;
    69         DATA_BLOB nt_resp;
    70         DATA_BLOB session_key;
    71        
    72         uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
    73 
    74         /* internal variables used by KEY_EXCH (client-supplied user session key */
    75         DATA_BLOB encrypted_session_key;
    76        
    77         /**
    78          * Callback to get the 'challenge' used for NTLM authentication. 
    79          *
    80          * @param ntlmssp_state This structure
    81          * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication
    82          *
    83          */
    84         const uint8_t *(*get_challenge)(const struct gensec_ntlmssp_state *);
    85 
    86         /**
    87          * Callback to find if the challenge used by NTLM authentication may be modified
    88          *
    89          * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the
    90          * current 'security=server' implementation.. 
    91          *
    92          * @param ntlmssp_state This structure
    93          * @return Can the challenge be set to arbitary values?
    94          *
    95          */
    96         bool (*may_set_challenge)(const struct gensec_ntlmssp_state *);
    97 
    98         /**
    99          * Callback to set the 'challenge' used for NTLM authentication. 
    100          *
    101          * The callback may use the void *auth_context to store state information, but the same value is always available
    102          * from the DATA_BLOB chal on this structure.
    103          *
    104          * @param ntlmssp_state This structure
    105          * @param challenge 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
    106          *
    107          */
    108         NTSTATUS (*set_challenge)(struct gensec_ntlmssp_state *, DATA_BLOB *challenge);
    109 
    110         /**
    111          * Callback to check the user's password. 
    112          *
    113          * The callback must reads the feilds of this structure for the information it needs on the user
    114          * @param ntlmssp_state This structure
    115          * @param nt_session_key If an NT session key is returned by the authentication process, return it here
    116          * @param lm_session_key If an LM session key is returned by the authentication process, return it here
    117          *
    118          */
    119         NTSTATUS (*check_password)(struct gensec_ntlmssp_state *,
    120                                    TALLOC_CTX *mem_ctx,
    121                                    DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
    122 
    123         const char *server_name;
    124 
    125         bool doing_ntlm2;
    126 
    127         union {
    128                 /* NTLM */
    129                 struct {
    130                         uint32_t seq_num;
    131                         struct arcfour_state *arcfour_state;
    132                 } ntlm;
    133 
    134                 /* NTLM2 */
    135                 struct {
    136                         uint32_t send_seq_num;
    137                         uint32_t recv_seq_num;
    138                         DATA_BLOB send_sign_key;
    139                         DATA_BLOB recv_sign_key;
    140                         struct arcfour_state *send_seal_arcfour_state;
    141                         struct arcfour_state *recv_seal_arcfour_state;
    142 
    143                         /* internal variables used by NTLM2 */
    144                         uint8_t session_nonce[16];
    145                 } ntlm2;
    146         } crypt;
    147 
     28        struct ntlmssp_state *ntlmssp_state;
    14829        struct auth_context *auth_context;
    149         struct auth_serversupplied_info *server_info;
     30        struct auth_user_info_dc *user_info_dc;
    15031};
    15132
     
    15334struct auth_session_info;
    15435
     36NTSTATUS gensec_ntlmssp_init(void);
     37
    15538#include "auth/ntlmssp/proto.h"
  • vendor/current/source4/auth/ntlmssp/ntlmssp_client.c

    r414 r740  
    2424#include "includes.h"
    2525#include "auth/ntlmssp/ntlmssp.h"
    26 #include "../librpc/gen_ndr/ntlmssp.h"
    2726#include "../lib/crypto/crypto.h"
    2827#include "../libcli/auth/libcli_auth.h"
     
    3029#include "auth/gensec/gensec.h"
    3130#include "param/param.h"
     31#include "libcli/auth/ntlmssp_private.h"
    3232
    3333/*********************************************************************
     
    4949                                DATA_BLOB in, DATA_BLOB *out)
    5050{
    51         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    52         const char *domain = gensec_ntlmssp_state->domain;
     51        struct gensec_ntlmssp_context *gensec_ntlmssp =
     52                talloc_get_type_abort(gensec_security->private_data,
     53                                      struct gensec_ntlmssp_context);
     54        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     55        const char *domain = ntlmssp_state->domain;
    5356        const char *workstation = cli_credentials_get_workstation(gensec_security->credentials);
     57        NTSTATUS status;
    5458
    5559        /* These don't really matter in the initial packet, so don't panic if they are not set */
     
    6266        }
    6367
    64         if (gensec_ntlmssp_state->unicode) {
    65                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
     68        if (ntlmssp_state->unicode) {
     69                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
    6670        } else {
    67                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
     71                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
    6872        }
    6973       
    70         if (gensec_ntlmssp_state->use_ntlmv2) {
    71                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     74        if (ntlmssp_state->use_ntlmv2) {
     75                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
    7276        }
    7377
    7478        /* generate the ntlmssp negotiate packet */
    75         msrpc_gen(out_mem_ctx,
     79        status = msrpc_gen(out_mem_ctx,
    7680                  out, "CddAA",
    7781                  "NTLMSSP",
    7882                  NTLMSSP_NEGOTIATE,
    79                   gensec_ntlmssp_state->neg_flags,
     83                  ntlmssp_state->neg_flags,
    8084                  domain,
    8185                  workstation);
    8286
    83         gensec_ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     87        if (!NT_STATUS_IS_OK(status)) {
     88                return status;
     89        }
     90
     91        ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
    8492
    8593        return NT_STATUS_MORE_PROCESSING_REQUIRED;
     
    100108                                  const DATA_BLOB in, DATA_BLOB *out)
    101109{
    102         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     110        struct gensec_ntlmssp_context *gensec_ntlmssp =
     111                talloc_get_type_abort(gensec_security->private_data,
     112                                      struct gensec_ntlmssp_context);
     113        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
    103114        uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
    104115        DATA_BLOB server_domain_blob;
     
    140151        debug_ntlmssp_flags(chal_flags);
    141152
    142         ntlmssp_handle_neg_flags(gensec_ntlmssp_state, chal_flags, gensec_ntlmssp_state->allow_lm_key);
    143 
    144         if (gensec_ntlmssp_state->unicode) {
     153        ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
     154
     155        if (ntlmssp_state->unicode) {
    145156                if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
    146157                        chal_parse_string = "CdUdbddB";
     
    174185        }
    175186
    176         gensec_ntlmssp_state->server_domain = server_domain;
     187        if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
     188                ntlmssp_state->server.is_standalone = true;
     189        } else {
     190                ntlmssp_state->server.is_standalone = false;
     191        }
     192        /* TODO: parse struct_blob and fill in the rest */
     193        ntlmssp_state->server.netbios_name = "";
     194        ntlmssp_state->server.netbios_domain = server_domain;
     195        ntlmssp_state->server.dns_name = "";
     196        ntlmssp_state->server.dns_domain = "";
    177197
    178198        if (challenge_blob.length != 8) {
     
    184204                                                 &user, &domain);
    185205
    186         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     206        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    187207                flags |= CLI_CRED_NTLM2;
    188208        }
    189         if (gensec_ntlmssp_state->use_ntlmv2) {
     209        if (ntlmssp_state->use_ntlmv2) {
    190210                flags |= CLI_CRED_NTLMv2_AUTH;
    191211        }
    192         if (gensec_ntlmssp_state->use_nt_response) {
     212        if (ntlmssp_state->use_nt_response) {
    193213                flags |= CLI_CRED_NTLM_AUTH;
    194214        }
    195         if (lp_client_lanman_auth(gensec_security->settings->lp_ctx)) {
     215        if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) {
    196216                flags |= CLI_CRED_LANMAN_AUTH;
    197217        }
     
    209229                /* LM Key is still possible, just silly.  Fortunetly
    210230                 * we require command line options to end up here */
    211                 /* gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */
     231                /* ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */
    212232        }
    213233
    214234        if (!(flags & CLI_CRED_NTLM2)) {
    215235                /* NTLM2 is incompatible... */
    216                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
     236                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    217237        }
    218238       
    219         if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    220             && lp_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) {
     239        if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
     240            && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) {
    221241                DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
    222242                if (lm_response.length == 24) {
     
    235255        /* Key exchange encryptes a new client-generated session key with
    236256           the password-derived key */
    237         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
     257        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    238258                /* Make up a new session key */
    239259                uint8_t client_session_key[16];
     
    241261
    242262                /* Encrypt the new session key with the old one */
    243                 encrypted_session_key = data_blob_talloc(gensec_ntlmssp_state,
     263                encrypted_session_key = data_blob_talloc(ntlmssp_state,
    244264                                                         client_session_key, sizeof(client_session_key));
    245265                dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
     
    252272
    253273        DEBUG(3, ("NTLMSSP: Set final flags:\n"));
    254         debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
     274        debug_ntlmssp_flags(ntlmssp_state->neg_flags);
    255275
    256276        /* this generates the actual auth packet */
    257         if (!msrpc_gen(mem_ctx,
     277        nt_status = msrpc_gen(mem_ctx,
    258278                       out, auth_gen_string,
    259279                       "NTLMSSP",
     
    265285                       cli_credentials_get_workstation(gensec_security->credentials),
    266286                       encrypted_session_key.data, encrypted_session_key.length,
    267                        gensec_ntlmssp_state->neg_flags)) {
     287                       ntlmssp_state->neg_flags);
     288        if (!NT_STATUS_IS_OK(nt_status)) {
    268289                talloc_free(mem_ctx);
    269                 return NT_STATUS_NO_MEMORY;
    270         }
    271 
    272         gensec_ntlmssp_state->session_key = session_key;
    273         talloc_steal(gensec_ntlmssp_state, session_key.data);
     290                return nt_status;
     291        }
     292
     293        ntlmssp_state->session_key = session_key;
     294        talloc_steal(ntlmssp_state, session_key.data);
    274295
    275296        talloc_steal(out_mem_ctx, out->data);
    276297
    277         gensec_ntlmssp_state->chal = challenge_blob;
    278         gensec_ntlmssp_state->lm_resp = lm_response;
    279         talloc_steal(gensec_ntlmssp_state->lm_resp.data, lm_response.data);
    280         gensec_ntlmssp_state->nt_resp = nt_response;
    281         talloc_steal(gensec_ntlmssp_state->nt_resp.data, nt_response.data);
    282 
    283         gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
     298        ntlmssp_state->chal = challenge_blob;
     299        ntlmssp_state->lm_resp = lm_response;
     300        talloc_steal(ntlmssp_state->lm_resp.data, lm_response.data);
     301        ntlmssp_state->nt_resp = nt_response;
     302        talloc_steal(ntlmssp_state->nt_resp.data, nt_response.data);
     303
     304        ntlmssp_state->expected_state = NTLMSSP_DONE;
    284305
    285306        if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) {
    286                 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
     307                nt_status = ntlmssp_sign_init(ntlmssp_state);
    287308                if (!NT_STATUS_IS_OK(nt_status)) {
    288309                        DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
     
    299320NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
    300321{
    301         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
     322        struct gensec_ntlmssp_context *gensec_ntlmssp;
     323        struct ntlmssp_state *ntlmssp_state;
    302324        NTSTATUS nt_status;
    303325
     
    305327        NT_STATUS_NOT_OK_RETURN(nt_status);
    306328
    307         gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    308 
    309         gensec_ntlmssp_state->role = NTLMSSP_CLIENT;
    310 
    311         gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
    312 
    313         gensec_ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
    314 
    315         gensec_ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true);
    316 
    317         gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->settings->lp_ctx)
     329        gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
     330                                               struct gensec_ntlmssp_context);
     331        ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     332
     333        ntlmssp_state->role = NTLMSSP_CLIENT;
     334
     335        ntlmssp_state->domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     336
     337        ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
     338
     339        ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true);
     340
     341        ntlmssp_state->allow_lm_key = (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)
    318342                                              && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
    319343                                                  || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
    320344
    321         gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
    322 
    323         gensec_ntlmssp_state->expected_state = NTLMSSP_INITIAL;
    324 
    325         gensec_ntlmssp_state->neg_flags =
     345        ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
     346
     347        ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     348
     349        ntlmssp_state->neg_flags =
    326350                NTLMSSP_NEGOTIATE_NTLM |
    327351                NTLMSSP_REQUEST_TARGET;
    328352
    329353        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
    330                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
     354                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
    331355        }
    332356
    333357        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
    334                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
     358                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
    335359        }
    336360
    337361        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
    338                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     362                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
    339363        }
    340364
    341365        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
    342                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;         
     366                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
    343367        }
    344368
    345369        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
    346                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
     370                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    347371        }
    348372
    349373        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
    350                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
     374                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
    351375        } else {
    352376                /* apparently we can't do ntlmv2 if we don't do ntlm2 */
    353                 gensec_ntlmssp_state->use_ntlmv2 = false;
     377                ntlmssp_state->use_ntlmv2 = false;
    354378        }
    355379
     
    364388                 * sealing.  (It is actually pulled out and used directly)
    365389                 */
    366                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     390                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    367391        }
    368392        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    369                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     393                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    370394        }
    371395        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    372                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    373         }
    374 
    375         gensec_security->private_data = gensec_ntlmssp_state;
     396                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     397                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
     398        }
    376399
    377400        return NT_STATUS_OK;
  • vendor/current/source4/auth/ntlmssp/ntlmssp_server.c

    r414 r740  
    2424#include "includes.h"
    2525#include "system/network.h"
     26#include "lib/tsocket/tsocket.h"
    2627#include "auth/ntlmssp/ntlmssp.h"
    27 #include "../librpc/gen_ndr/ntlmssp.h"
     28#include "../librpc/gen_ndr/ndr_ntlmssp.h"
     29#include "../libcli/auth/ntlmssp_ndr.h"
     30#include "../libcli/auth/ntlmssp_private.h"
    2831#include "../libcli/auth/libcli_auth.h"
    2932#include "../lib/crypto/crypto.h"
    3033#include "auth/gensec/gensec.h"
     34#include "auth/gensec/gensec_proto.h"
    3135#include "auth/auth.h"
    32 #include "auth/ntlm/auth_proto.h"
    3336#include "param/param.h"
    34 #include "auth/session_proto.h"
    35 
    36 /**
    37  * Set a username on an NTLMSSP context - ensures it is talloc()ed
    38  *
    39  */
    40 
    41 static NTSTATUS ntlmssp_set_username(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *user)
    42 {
    43         if (!user) {
    44                 /* it should be at least "" */
    45                 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
    46                 return NT_STATUS_INVALID_PARAMETER;
    47         }
    48         gensec_ntlmssp_state->user = talloc_strdup(gensec_ntlmssp_state, user);
    49         if (!gensec_ntlmssp_state->user) {
    50                 return NT_STATUS_NO_MEMORY;
    51         }
    52         return NT_STATUS_OK;
    53 }
    54 
    55 /**
    56  * Set a domain on an NTLMSSP context - ensures it is talloc()ed
    57  *
    58  */
    59 static NTSTATUS ntlmssp_set_domain(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *domain)
    60 {
    61         gensec_ntlmssp_state->domain = talloc_strdup(gensec_ntlmssp_state, domain);
    62         if (!gensec_ntlmssp_state->domain) {
    63                 return NT_STATUS_NO_MEMORY;
    64         }
    65         return NT_STATUS_OK;
    66 }
    67 
    68 /**
    69  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
    70  *
    71  */
    72 static NTSTATUS ntlmssp_set_workstation(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *workstation)
    73 {
    74         gensec_ntlmssp_state->workstation = talloc_strdup(gensec_ntlmssp_state, workstation);
    75         if (!gensec_ntlmssp_state->workstation) {
    76                 return NT_STATUS_NO_MEMORY;
    77         }
    78         return NT_STATUS_OK;
    79 }
    80 
    81 /**
    82  * Determine correct target name flags for reply, given server role
    83  * and negotiated flags
    84  *
    85  * @param gensec_ntlmssp_state NTLMSSP State
    86  * @param neg_flags The flags from the packet
    87  * @param chal_flags The flags to be set in the reply packet
    88  * @return The 'target name' string.
    89  */
    90 
    91 static const char *ntlmssp_target_name(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    92                                        uint32_t neg_flags, uint32_t *chal_flags)
    93 {
    94         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
    95                 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
    96                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
    97                 if (gensec_ntlmssp_state->server_role == ROLE_STANDALONE) {
    98                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
    99                         return gensec_ntlmssp_state->server_name;
    100                 } else {
    101                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
    102                         return gensec_ntlmssp_state->domain;
    103                 };
    104         } else {
    105                 return "";
    106         }
    107 }
    108 
    109 
    110 
    111 /**
    112  * Next state function for the Negotiate packet
    113  *
     37
     38/**
     39 * Next state function for the Negotiate packet (GENSEC wrapper)
     40 *
    11441 * @param gensec_security GENSEC state
    11542 * @param out_mem_ctx Memory context for *out
    11643 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    11744 * @param out The reply, as an allocated DATA_BLOB, caller to free.
    118  * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
    119  */
    120 
    121 NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
    122                                   TALLOC_CTX *out_mem_ctx,
    123                                   const DATA_BLOB in, DATA_BLOB *out)
    124 {
    125         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    126         DATA_BLOB struct_blob;
    127         uint32_t neg_flags = 0;
    128         uint32_t ntlmssp_command, chal_flags;
    129         const uint8_t *cryptkey;
    130         const char *target_name;
    131 
    132         /* parse the NTLMSSP packet */
    133 #if 0
    134         file_save("ntlmssp_negotiate.dat", request.data, request.length);
    135 #endif
    136 
    137         if (in.length) {
    138                 if ((in.length < 16) || !msrpc_parse(out_mem_ctx,
    139                                                          &in, "Cdd",
    140                                                          "NTLMSSP",
    141                                                          &ntlmssp_command,
    142                                                          &neg_flags)) {
    143                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse "
    144                                 "NTLMSSP Negotiate of length %u:\n",
    145                                 (unsigned int)in.length ));
    146                         dump_data(2, in.data, in.length);
    147                         return NT_STATUS_INVALID_PARAMETER;
    148                 }
    149                 debug_ntlmssp_flags(neg_flags);
    150         }
    151        
    152         ntlmssp_handle_neg_flags(gensec_ntlmssp_state, neg_flags, gensec_ntlmssp_state->allow_lm_key);
    153 
    154         /* Ask our caller what challenge they would like in the packet */
    155         cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
    156         if (!cryptkey) {
    157                 DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
    158                 return NT_STATUS_INTERNAL_ERROR;
    159         }
    160 
    161         /* Check if we may set the challenge */
    162         if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
    163                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    164         }
    165 
    166         /* The flags we send back are not just the negotiated flags,
    167          * they are also 'what is in this packet'.  Therfore, we
    168          * operate on 'chal_flags' from here on
    169          */
    170 
    171         chal_flags = gensec_ntlmssp_state->neg_flags;
    172 
    173         /* get the right name to fill in as 'target' */
    174         target_name = ntlmssp_target_name(gensec_ntlmssp_state,
    175                                           neg_flags, &chal_flags);
    176         if (target_name == NULL)
     45 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
     46 */
     47
     48NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
     49                                         TALLOC_CTX *out_mem_ctx,
     50                                         const DATA_BLOB request, DATA_BLOB *reply)
     51{
     52        struct gensec_ntlmssp_context *gensec_ntlmssp =
     53                talloc_get_type_abort(gensec_security->private_data,
     54                                      struct gensec_ntlmssp_context);
     55        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     56        return ntlmssp_server_negotiate(ntlmssp_state, out_mem_ctx, request, reply);
     57}
     58
     59/**
     60 * Next state function for the Authenticate packet (GENSEC wrapper)
     61 *
     62 * @param gensec_security GENSEC state
     63 * @param out_mem_ctx Memory context for *out
     64 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
     65 * @param out The reply, as an allocated DATA_BLOB, caller to free.
     66 * @return Errors or NT_STATUS_OK if authentication sucessful
     67 */
     68
     69NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security,
     70                                    TALLOC_CTX *out_mem_ctx,
     71                                    const DATA_BLOB in, DATA_BLOB *out)
     72{
     73        struct gensec_ntlmssp_context *gensec_ntlmssp =
     74                talloc_get_type_abort(gensec_security->private_data,
     75                                      struct gensec_ntlmssp_context);
     76        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     77        return ntlmssp_server_auth(ntlmssp_state, out_mem_ctx, in, out);
     78}
     79
     80/**
     81 * Return the challenge as determined by the authentication subsystem
     82 * @return an 8 byte random challenge
     83 */
     84
     85static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
     86                                           uint8_t chal[8])
     87{
     88        struct gensec_ntlmssp_context *gensec_ntlmssp =
     89                talloc_get_type_abort(ntlmssp_state->callback_private,
     90                                      struct gensec_ntlmssp_context);
     91        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     92        NTSTATUS status;
     93
     94        status = auth_context->get_challenge(auth_context, chal);
     95        if (!NT_STATUS_IS_OK(status)) {
     96                DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
     97                        nt_errstr(status)));
     98                return status;
     99        }
     100
     101        return NT_STATUS_OK;
     102}
     103
     104/**
     105 * Some authentication methods 'fix' the challenge, so we may not be able to set it
     106 *
     107 * @return If the effective challenge used by the auth subsystem may be modified
     108 */
     109static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
     110{
     111        struct gensec_ntlmssp_context *gensec_ntlmssp =
     112                talloc_get_type_abort(ntlmssp_state->callback_private,
     113                                      struct gensec_ntlmssp_context);
     114        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     115
     116        return auth_context->challenge_may_be_modified(auth_context);
     117}
     118
     119/**
     120 * NTLM2 authentication modifies the effective challenge,
     121 * @param challenge The new challenge value
     122 */
     123static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
     124{
     125        struct gensec_ntlmssp_context *gensec_ntlmssp =
     126                talloc_get_type_abort(ntlmssp_state->callback_private,
     127                                      struct gensec_ntlmssp_context);
     128        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     129        NTSTATUS nt_status;
     130        const uint8_t *chal;
     131
     132        if (challenge->length != 8) {
    177133                return NT_STATUS_INVALID_PARAMETER;
    178 
    179         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    180         gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    181 
    182         /* This creates the 'blob' of names that appears at the end of the packet */
    183         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     134        }
     135
     136        chal = challenge->data;
     137
     138        nt_status = auth_context->set_challenge(auth_context,
     139                                                chal,
     140                                                "NTLMSSP callback (NTLM2)");
     141
     142        return nt_status;
     143}
     144
     145/**
     146 * Check the password on an NTLMSSP login. 
     147 *
     148 * Return the session keys used on the connection.
     149 */
     150
     151static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
     152                                            TALLOC_CTX *mem_ctx,
     153                                            DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
     154{
     155        struct gensec_ntlmssp_context *gensec_ntlmssp =
     156                talloc_get_type_abort(ntlmssp_state->callback_private,
     157                                      struct gensec_ntlmssp_context);
     158        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     159        NTSTATUS nt_status;
     160        struct auth_usersupplied_info *user_info;
     161
     162        user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info);
     163        if (!user_info) {
     164                return NT_STATUS_NO_MEMORY;
     165        }
     166
     167        user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
     168        user_info->flags = 0;
     169        user_info->mapped_state = false;
     170        user_info->client.account_name = ntlmssp_state->user;
     171        user_info->client.domain_name = ntlmssp_state->domain;
     172        user_info->workstation_name = ntlmssp_state->client.netbios_name;
     173        user_info->remote_host = gensec_get_remote_address(gensec_ntlmssp->gensec_security);
     174
     175        user_info->password_state = AUTH_PASSWORD_RESPONSE;
     176        user_info->password.response.lanman = ntlmssp_state->lm_resp;
     177        user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data);
     178        user_info->password.response.nt = ntlmssp_state->nt_resp;
     179        user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
     180
     181        nt_status = auth_context->check_password(auth_context,
     182                                                 gensec_ntlmssp,
     183                                                 user_info,
     184                                                 &gensec_ntlmssp->user_info_dc);
     185        talloc_free(user_info);
     186        NT_STATUS_NOT_OK_RETURN(nt_status);
     187
     188        if (gensec_ntlmssp->user_info_dc->user_session_key.length) {
     189                DEBUG(10, ("Got NT session key of length %u\n",
     190                           (unsigned)gensec_ntlmssp->user_info_dc->user_session_key.length));
     191                *user_session_key = gensec_ntlmssp->user_info_dc->user_session_key;
     192                talloc_steal(mem_ctx, user_session_key->data);
     193                gensec_ntlmssp->user_info_dc->user_session_key = data_blob_null;
     194        }
     195        if (gensec_ntlmssp->user_info_dc->lm_session_key.length) {
     196                DEBUG(10, ("Got LM session key of length %u\n",
     197                           (unsigned)gensec_ntlmssp->user_info_dc->lm_session_key.length));
     198                *lm_session_key = gensec_ntlmssp->user_info_dc->lm_session_key;
     199                talloc_steal(mem_ctx, lm_session_key->data);
     200                gensec_ntlmssp->user_info_dc->lm_session_key = data_blob_null;
     201        }
     202        return nt_status;
     203}
     204
     205/**
     206 * Return the credentials of a logged on user, including session keys
     207 * etc.
     208 *
     209 * Only valid after a successful authentication
     210 *
     211 * May only be called once per authentication.
     212 *
     213 */
     214
     215NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
     216                                     struct auth_session_info **session_info)
     217{
     218        NTSTATUS nt_status;
     219        struct gensec_ntlmssp_context *gensec_ntlmssp =
     220                talloc_get_type_abort(gensec_security->private_data,
     221                                      struct gensec_ntlmssp_context);
     222        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     223
     224        nt_status = gensec_generate_session_info(ntlmssp_state,
     225                                                 gensec_security,
     226                                                 gensec_ntlmssp->user_info_dc,
     227                                                 session_info);
     228        NT_STATUS_NOT_OK_RETURN(nt_status);
     229
     230        (*session_info)->session_key = data_blob_talloc(*session_info,
     231                                                        ntlmssp_state->session_key.data,
     232                                                        ntlmssp_state->session_key.length);
     233
     234        return NT_STATUS_OK;
     235}
     236
     237/**
     238 * Start NTLMSSP on the server side
     239 *
     240 */
     241NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
     242{
     243        NTSTATUS nt_status;
     244        struct ntlmssp_state *ntlmssp_state;
     245        struct gensec_ntlmssp_context *gensec_ntlmssp;
     246
     247        nt_status = gensec_ntlmssp_start(gensec_security);
     248        NT_STATUS_NOT_OK_RETURN(nt_status);
     249
     250        gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
     251                                               struct gensec_ntlmssp_context);
     252        ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     253
     254        ntlmssp_state->role = NTLMSSP_SERVER;
     255
     256        ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
     257
     258        ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx)
     259                                          && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
     260
     261        ntlmssp_state->neg_flags =
     262                NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
     263
     264        ntlmssp_state->lm_resp = data_blob(NULL, 0);
     265        ntlmssp_state->nt_resp = data_blob(NULL, 0);
     266
     267        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
     268                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
     269        }
     270
     271        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
     272                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
     273        }
     274
     275        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
     276                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
     277        }
     278
     279        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
     280                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     281        }
     282
     283        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
     284                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     285        }
     286
     287        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     288                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     289        }
     290        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     291                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
     292        }
     293
     294        gensec_ntlmssp->auth_context = gensec_security->auth_context;
     295
     296        ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
     297        ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
     298        ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
     299        ntlmssp_state->check_password = auth_ntlmssp_check_password;
     300        if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) {
     301                ntlmssp_state->server.is_standalone = true;
     302        } else {
     303                ntlmssp_state->server.is_standalone = false;
     304        }
     305
     306        ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
     307
     308        ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     309
     310        {
    184311                char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
    185                 const char *target_name_dns = "";
    186312
    187313                /* Find out the DNS domain name */
    188314                dnsdomname[0] = '\0';
    189                 safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    190                 strlower_m(dnsdomname);
     315                safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    191316
    192317                /* Find out the DNS host name */
    193                 safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);
     318                safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1);
    194319                if (dnsdomname[0] != '\0') {
    195320                        safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
     
    198323                strlower_m(dnsname);
    199324
    200                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
    201                         target_name_dns = dnsdomname;
    202                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
    203                         target_name_dns = dnsname;
    204                 }
    205 
    206                 msrpc_gen(out_mem_ctx,
    207                           &struct_blob, "aaaaa",
    208                           MsvAvNbDomainName, target_name,
    209                           MsvAvNbComputerName, gensec_ntlmssp_state->server_name,
    210                           MsvAvDnsDomainName, dnsdomname,
    211                           MsvAvDnsComputerName, dnsname,
    212                           MsvAvEOL, "");
    213         } else {
    214                 struct_blob = data_blob(NULL, 0);
    215         }
    216 
    217         {
    218                 /* Marshal the packet in the right format, be it unicode or ASCII */
    219                 const char *gen_string;
    220                 if (gensec_ntlmssp_state->unicode) {
    221                         gen_string = "CdUdbddB";
    222                 } else {
    223                         gen_string = "CdAdbddB";
    224                 }
    225                
    226                 msrpc_gen(out_mem_ctx,
    227                           out, gen_string,
    228                           "NTLMSSP",
    229                           NTLMSSP_CHALLENGE,
    230                           target_name,
    231                           chal_flags,
    232                           cryptkey, 8,
    233                           0, 0,
    234                           struct_blob.data, struct_blob.length);
    235         }
    236                
    237         gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    238 
    239         return NT_STATUS_MORE_PROCESSING_REQUIRED;
    240 }
    241 
    242 /**
    243  * Next state function for the Authenticate packet
    244  *
    245  * @param gensec_ntlmssp_state NTLMSSP State
    246  * @param request The request, as a DATA_BLOB
    247  * @return Errors or NT_STATUS_OK.
    248  */
    249 
    250 static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    251                                        const DATA_BLOB request)
    252 {
    253         uint32_t ntlmssp_command, auth_flags;
    254         NTSTATUS nt_status;
    255 
    256         uint8_t session_nonce_hash[16];
    257 
    258         const char *parse_string;
    259         char *domain = NULL;
    260         char *user = NULL;
    261         char *workstation = NULL;
    262 
    263 #if 0
    264         file_save("ntlmssp_auth.dat", request.data, request.length);
    265 #endif
    266 
    267         if (gensec_ntlmssp_state->unicode) {
    268                 parse_string = "CdBBUUUBd";
    269         } else {
    270                 parse_string = "CdBBAAABd";
    271         }
    272 
    273         /* zero these out */
    274         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    275         data_blob_free(&gensec_ntlmssp_state->nt_resp);
    276         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    277 
    278         gensec_ntlmssp_state->user = NULL;
    279         gensec_ntlmssp_state->domain = NULL;
    280         gensec_ntlmssp_state->workstation = NULL;
    281 
    282         /* now the NTLMSSP encoded auth hashes */
    283         if (!msrpc_parse(gensec_ntlmssp_state,
    284                          &request, parse_string,
    285                          "NTLMSSP",
    286                          &ntlmssp_command,
    287                          &gensec_ntlmssp_state->lm_resp,
    288                          &gensec_ntlmssp_state->nt_resp,
    289                          &domain,
    290                          &user,
    291                          &workstation,
    292                          &gensec_ntlmssp_state->encrypted_session_key,
    293                          &auth_flags)) {
    294                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
    295                 dump_data(10, request.data, request.length);
    296 
    297                 /* zero this out */
    298                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    299                 auth_flags = 0;
    300                
    301                 /* Try again with a shorter string (Win9X truncates this packet) */
    302                 if (gensec_ntlmssp_state->unicode) {
    303                         parse_string = "CdBBUUU";
    304                 } else {
    305                         parse_string = "CdBBAAA";
    306                 }
    307 
    308                 /* now the NTLMSSP encoded auth hashes */
    309                 if (!msrpc_parse(gensec_ntlmssp_state,
    310                                  &request, parse_string,
    311                                  "NTLMSSP",
    312                                  &ntlmssp_command,
    313                                  &gensec_ntlmssp_state->lm_resp,
    314                                  &gensec_ntlmssp_state->nt_resp,
    315                                  &domain,
    316                                  &user,
    317                                  &workstation)) {
    318                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
    319                         dump_data(2, request.data, request.length);
    320 
    321                         return NT_STATUS_INVALID_PARAMETER;
    322                 }
    323         }
    324 
    325         if (auth_flags)
    326                 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, auth_flags, gensec_ntlmssp_state->allow_lm_key);
    327 
    328         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(gensec_ntlmssp_state, domain))) {
    329                 /* zero this out */
    330                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    331                 return nt_status;
    332         }
    333 
    334         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(gensec_ntlmssp_state, user))) {
    335                 /* zero this out */
    336                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    337                 return nt_status;
    338         }
    339 
    340         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state, workstation))) {
    341                 /* zero this out */
    342                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    343                 return nt_status;
    344         }
    345 
    346         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
    347                  gensec_ntlmssp_state->user, gensec_ntlmssp_state->domain, gensec_ntlmssp_state->workstation, (unsigned long)gensec_ntlmssp_state->lm_resp.length, (unsigned long)gensec_ntlmssp_state->nt_resp.length));
    348 
    349 #if 0
    350         file_save("nthash1.dat",  &gensec_ntlmssp_state->nt_resp.data,  &gensec_ntlmssp_state->nt_resp.length);
    351         file_save("lmhash1.dat",  &gensec_ntlmssp_state->lm_resp.data,  &gensec_ntlmssp_state->lm_resp.length);
    352 #endif
    353 
    354         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
    355            client challenge
    356        
    357            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
    358         */
    359         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    360                 if (gensec_ntlmssp_state->nt_resp.length == 24 && gensec_ntlmssp_state->lm_resp.length == 24) {
    361                         struct MD5Context md5_session_nonce_ctx;
    362                         SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data
    363                                    && gensec_ntlmssp_state->internal_chal.length == 8);
    364                        
    365                         gensec_ntlmssp_state->doing_ntlm2 = true;
    366 
    367                         memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
    368                         memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
    369                        
    370                         MD5Init(&md5_session_nonce_ctx);
    371                         MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 16);
    372                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
    373                        
    374                         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state,
    375                                                                session_nonce_hash, 8);
    376 
    377                         /* LM response is no longer useful, zero it out */
    378                         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    379 
    380                         /* We changed the effective challenge - set it */
    381                         if (!NT_STATUS_IS_OK(nt_status =
    382                                              gensec_ntlmssp_state->set_challenge(gensec_ntlmssp_state,
    383                                                                                  &gensec_ntlmssp_state->chal))) {
    384                                 /* zero this out */
    385                                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    386                                 return nt_status;
    387                         }
    388 
    389                         /* LM Key is incompatible... */
    390                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    391                 }
    392         }
     325                ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state,
     326                                                                      dnsname);
     327                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);
     328
     329                ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state,
     330                                                                        dnsdomname);
     331                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
     332        }
     333
    393334        return NT_STATUS_OK;
    394335}
    395336
    396 /**
    397  * Next state function for the Authenticate packet
    398  * (after authentication - figures out the session keys etc)
    399  *
    400  * @param gensec_ntlmssp_state NTLMSSP State
    401  * @return Errors or NT_STATUS_OK.
    402  */
    403 
    404 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
    405                                         DATA_BLOB *user_session_key,
    406                                         DATA_BLOB *lm_session_key)
    407 {
    408         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    409         NTSTATUS nt_status;
    410         DATA_BLOB session_key = data_blob(NULL, 0);
    411 
    412         if (user_session_key)
    413                 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
    414 
    415         if (lm_session_key)
    416                 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
    417 
    418         /* Handle the different session key derivation for NTLM2 */
    419         if (gensec_ntlmssp_state->doing_ntlm2) {
    420                 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
    421                         session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    422                         hmac_md5(user_session_key->data, gensec_ntlmssp_state->crypt.ntlm2.session_nonce,
    423                                  sizeof(gensec_ntlmssp_state->crypt.ntlm2.session_nonce), session_key.data);
    424                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
    425                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
    426                        
    427                 } else {
    428                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
    429                         session_key = data_blob(NULL, 0);
    430                 }
    431         } else if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    432                 /* Ensure we can never get here on NTLMv2 */
    433                 && (gensec_ntlmssp_state->nt_resp.length == 0 || gensec_ntlmssp_state->nt_resp.length == 24)) {
    434 
    435                 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
    436                         if (gensec_ntlmssp_state->lm_resp.data && gensec_ntlmssp_state->lm_resp.length == 24) {
    437                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    438                                 SMBsesskeygen_lm_sess_key(lm_session_key->data, gensec_ntlmssp_state->lm_resp.data,
    439                                                           session_key.data);
    440                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    441                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    442                         } else {
    443                                
    444                                 /* When there is no LM response, just use zeros */
    445                                 static const uint8_t zeros[24];
    446                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    447                                 SMBsesskeygen_lm_sess_key(zeros, zeros,
    448                                                           session_key.data);
    449                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    450                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    451                         }
    452                 } else {
    453                         /* LM Key not selected */
    454                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    455 
    456                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
    457                         session_key = data_blob(NULL, 0);
    458                 }
    459 
    460         } else if (user_session_key && user_session_key->data) {
    461                 session_key = data_blob_talloc(gensec_ntlmssp_state, user_session_key->data, user_session_key->length);
    462                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
    463                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    464 
    465                 /* LM Key not selected */
    466                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    467 
    468         } else if (lm_session_key && lm_session_key->data) {
    469                 /* Very weird to have LM key, but no user session key, but anyway.. */
    470                 session_key = data_blob_talloc(gensec_ntlmssp_state, lm_session_key->data, lm_session_key->length);
    471                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
    472                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    473 
    474                 /* LM Key not selected */
    475                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    476 
    477         } else {
    478                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
    479                 session_key = data_blob(NULL, 0);
    480 
    481                 /* LM Key not selected */
    482                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    483         }
    484 
    485         /* With KEY_EXCH, the client supplies the proposed session key,
    486            but encrypts it with the long-term key */
    487         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    488                 if (!gensec_ntlmssp_state->encrypted_session_key.data
    489                     || gensec_ntlmssp_state->encrypted_session_key.length != 16) {
    490                         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    491                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
    492                                   (unsigned)gensec_ntlmssp_state->encrypted_session_key.length));
    493                         return NT_STATUS_INVALID_PARAMETER;
    494                 } else if (!session_key.data || session_key.length != 16) {
    495                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
    496                                   (unsigned)session_key.length));
    497                         gensec_ntlmssp_state->session_key = session_key;
    498                 } else {
    499                         dump_data_pw("KEY_EXCH session key (enc):\n",
    500                                      gensec_ntlmssp_state->encrypted_session_key.data,
    501                                      gensec_ntlmssp_state->encrypted_session_key.length);
    502                         arcfour_crypt(gensec_ntlmssp_state->encrypted_session_key.data,
    503                                       session_key.data,
    504                                       gensec_ntlmssp_state->encrypted_session_key.length);
    505                         gensec_ntlmssp_state->session_key = data_blob_talloc(gensec_ntlmssp_state,
    506                                                                       gensec_ntlmssp_state->encrypted_session_key.data,
    507                                                                       gensec_ntlmssp_state->encrypted_session_key.length);
    508                         dump_data_pw("KEY_EXCH session key:\n", gensec_ntlmssp_state->encrypted_session_key.data,
    509                                      gensec_ntlmssp_state->encrypted_session_key.length);
    510                         talloc_free(session_key.data);
    511                 }
    512         } else {
    513                 gensec_ntlmssp_state->session_key = session_key;
    514         }
    515 
    516         if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
    517             || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
    518                 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
    519         } else {
    520                 nt_status = NT_STATUS_OK;
    521         }
    522 
    523         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    524        
    525         /* allow arbitarily many authentications, but watch that this will cause a
    526            memory leak, until the gensec_ntlmssp_state is shutdown
    527         */
    528 
    529         if (gensec_ntlmssp_state->server_multiple_authentications) {
    530                 gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    531         } else {
    532                 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
    533         }
    534 
    535         return nt_status;
    536 }
    537 
    538 
    539 /**
    540  * Next state function for the Authenticate packet
    541  *
    542  * @param gensec_security GENSEC state
    543  * @param out_mem_ctx Memory context for *out
    544  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    545  * @param out The reply, as an allocated DATA_BLOB, caller to free.
    546  * @return Errors or NT_STATUS_OK if authentication sucessful
    547  */
    548 
    549 NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security,
    550                              TALLOC_CTX *out_mem_ctx,
    551                              const DATA_BLOB in, DATA_BLOB *out)
    552 {       
    553         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    554         DATA_BLOB user_session_key = data_blob(NULL, 0);
    555         DATA_BLOB lm_session_key = data_blob(NULL, 0);
    556         NTSTATUS nt_status;
    557 
    558         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
    559         if (!mem_ctx) {
    560                 return NT_STATUS_NO_MEMORY;
    561         }
    562 
    563         /* zero the outbound NTLMSSP packet */
    564         *out = data_blob_talloc(out_mem_ctx, NULL, 0);
    565 
    566         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) {
    567                 talloc_free(mem_ctx);
    568                 return nt_status;
    569         }
    570 
    571         /*
    572          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
    573          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
    574          * smb.conf file) and no NTLMv2 response was sent then the password check
    575          * will fail here. JRA.
    576          */
    577 
    578         /* Finally, actually ask if the password is OK */
    579 
    580         if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx,
    581                                                                               &user_session_key, &lm_session_key))) {
    582                 talloc_free(mem_ctx);
    583                 return nt_status;
    584         }
    585        
    586         if (gensec_security->want_features
    587             & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) {
    588                 nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key);
    589                 talloc_free(mem_ctx);
    590                 return nt_status;
    591         } else {
    592                 gensec_ntlmssp_state->session_key = data_blob(NULL, 0);
    593                 talloc_free(mem_ctx);
    594                 return NT_STATUS_OK;
    595         }
    596 }
    597 
    598 /**
    599  * Return the challenge as determined by the authentication subsystem
    600  * @return an 8 byte random challenge
    601  */
    602 
    603 static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    604 {
    605         NTSTATUS status;
    606         const uint8_t *chal;
    607 
    608         status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);
    609         if (!NT_STATUS_IS_OK(status)) {
    610                 DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
    611                         nt_errstr(status)));
    612                 return NULL;
    613         }
    614 
    615         return chal;
    616 }
    617 
    618 /**
    619  * Some authentication methods 'fix' the challenge, so we may not be able to set it
    620  *
    621  * @return If the effective challenge used by the auth subsystem may be modified
    622  */
    623 static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    624 {
    625         return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
    626 }
    627 
    628 /**
    629  * NTLM2 authentication modifies the effective challenge,
    630  * @param challenge The new challenge value
    631  */
    632 static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *challenge)
    633 {
    634         NTSTATUS nt_status;
    635         struct auth_context *auth_context = gensec_ntlmssp_state->auth_context;
    636         const uint8_t *chal;
    637 
    638         if (challenge->length != 8) {
    639                 return NT_STATUS_INVALID_PARAMETER;
    640         }
    641 
    642         chal = challenge->data;
    643 
    644         nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context,
    645                                                                       chal,
    646                                                                       "NTLMSSP callback (NTLM2)");
    647 
    648         return nt_status;
    649 }
    650 
    651 /**
    652  * Check the password on an NTLMSSP login. 
    653  *
    654  * Return the session keys used on the connection.
    655  */
    656 
    657 static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    658                                             TALLOC_CTX *mem_ctx,
    659                                             DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
    660 {
    661         NTSTATUS nt_status;
    662         struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info);
    663         if (!user_info) {
    664                 return NT_STATUS_NO_MEMORY;
    665         }
    666 
    667         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
    668         user_info->flags = 0;
    669         user_info->mapped_state = false;
    670         user_info->client.account_name = gensec_ntlmssp_state->user;
    671         user_info->client.domain_name = gensec_ntlmssp_state->domain;
    672         user_info->workstation_name = gensec_ntlmssp_state->workstation;
    673         user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security);
    674 
    675         user_info->password_state = AUTH_PASSWORD_RESPONSE;
    676         user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp;
    677         user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data);
    678         user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;
    679         user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);
    680 
    681         nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context,
    682                                                                        mem_ctx,
    683                                                                        user_info,
    684                                                                        &gensec_ntlmssp_state->server_info);
    685         talloc_free(user_info);
    686         NT_STATUS_NOT_OK_RETURN(nt_status);
    687 
    688         talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info);
    689 
    690         if (gensec_ntlmssp_state->server_info->user_session_key.length) {
    691                 DEBUG(10, ("Got NT session key of length %u\n",
    692                            (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length));
    693                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) {
    694                         return NT_STATUS_NO_MEMORY;
    695                 }
    696 
    697                 *user_session_key = gensec_ntlmssp_state->server_info->user_session_key;
    698         }
    699         if (gensec_ntlmssp_state->server_info->lm_session_key.length) {
    700                 DEBUG(10, ("Got LM session key of length %u\n",
    701                            (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length));
    702                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) {
    703                         return NT_STATUS_NO_MEMORY;
    704                 }
    705 
    706                 *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key;
    707         }
    708         return nt_status;
    709 }
    710 
    711 /**
    712  * Return the credentials of a logged on user, including session keys
    713  * etc.
    714  *
    715  * Only valid after a successful authentication
    716  *
    717  * May only be called once per authentication.
    718  *
    719  */
    720 
    721 NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
    722                                      struct auth_session_info **session_info)
    723 {
    724         NTSTATUS nt_status;
    725         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    726 
    727         nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info);
    728         NT_STATUS_NOT_OK_RETURN(nt_status);
    729 
    730         (*session_info)->session_key = data_blob_talloc(*session_info,
    731                                                         gensec_ntlmssp_state->session_key.data,
    732                                                         gensec_ntlmssp_state->session_key.length);
    733 
    734         return NT_STATUS_OK;
    735 }
    736 
    737 /**
    738  * Start NTLMSSP on the server side
    739  *
    740  */
    741 NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
    742 {
    743         NTSTATUS nt_status;
    744         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
    745 
    746         nt_status = gensec_ntlmssp_start(gensec_security);
    747         NT_STATUS_NOT_OK_RETURN(nt_status);
    748 
    749         gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    750 
    751         gensec_ntlmssp_state->role = NTLMSSP_SERVER;
    752 
    753         gensec_ntlmssp_state->workstation = NULL;
    754         gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);
    755 
    756         gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
    757 
    758         gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
    759 
    760         gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx)
    761                                           && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
    762 
    763         gensec_ntlmssp_state->server_multiple_authentications = false;
    764        
    765         gensec_ntlmssp_state->neg_flags =
    766                 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
    767 
    768         gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);
    769         gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);
    770         gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);
    771 
    772         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
    773                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
    774         }
    775 
    776         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
    777                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
    778         }
    779 
    780         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
    781                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;         
    782         }
    783 
    784         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
    785                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
    786         }
    787 
    788         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
    789                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
    790         }
    791 
    792         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    793                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    794         }
    795         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    796                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    797         }
    798 
    799         gensec_ntlmssp_state->auth_context = gensec_security->auth_context;
    800 
    801         gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
    802         gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
    803         gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
    804         gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;
    805         gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);
    806 
    807         return NT_STATUS_OK;
    808 }
    809 
  • vendor/current/source4/auth/ntlmssp/ntlmssp_sign.c

    r414 r740  
    1 /* 
     1/*
    22 *  Unix SMB/CIFS implementation.
    33 *  Version 3.0
     
    55 *  Copyright (C) Luke Kenneth Casson Leighton 1996-2001
    66 *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2005
    7  * 
     7 *
    88 *  This program is free software; you can redistribute it and/or modify
    99 *  it under the terms of the GNU General Public License as published by
    1010 *  the Free Software Foundation; either version 3 of the License, or
    1111 *  (at your option) any later version.
    12  * 
     12 *
    1313 *  This program is distributed in the hope that it will be useful,
    1414 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616 *  GNU General Public License for more details.
    17  * 
     17 *
    1818 *  You should have received a copy of the GNU General Public License
    1919 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     
    2222#include "includes.h"
    2323#include "auth/ntlmssp/ntlmssp.h"
    24 #include "../librpc/gen_ndr/ntlmssp.h"
    25 #include "../libcli/auth/libcli_auth.h"
    26 #include "../lib/crypto/crypto.h"
    2724#include "auth/gensec/gensec.h"
     25#include "../libcli/auth/ntlmssp_private.h"
    2826
    29 #define CLI_SIGN "session key to client-to-server signing key magic constant"
    30 #define CLI_SEAL "session key to client-to-server sealing key magic constant"
    31 #define SRV_SIGN "session key to server-to-client signing key magic constant"
    32 #define SRV_SEAL "session key to server-to-client sealing key magic constant"
    33 
    34 /**
    35  * Some notes on the NTLM2 code:
    36  *
    37  * NTLM2 is a AEAD system.  This means that the data encrypted is not
    38  * all the data that is signed.  In DCE-RPC case, the headers of the
    39  * DCE-RPC packets are also signed.  This prevents some of the
    40  * fun-and-games one might have by changing them.
    41  *
    42  */
    43 
    44 static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx,
    45                             DATA_BLOB *subkey,
    46                             DATA_BLOB session_key,
    47                             const char *constant)
    48 {
    49         struct MD5Context ctx3;
    50         *subkey = data_blob_talloc(mem_ctx, NULL, 16);
    51         MD5Init(&ctx3);
    52         MD5Update(&ctx3, session_key.data, session_key.length);
    53         MD5Update(&ctx3, (const uint8_t *)constant, strlen(constant)+1);
    54         MD5Final(subkey->data, &ctx3);
    55 }
    56 
    57 enum ntlmssp_direction {
    58         NTLMSSP_SEND,
    59         NTLMSSP_RECEIVE
    60 };
    61 
    62 static NTSTATUS ntlmssp_make_packet_signature(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    63                                               TALLOC_CTX *sig_mem_ctx,
    64                                               const uint8_t *data, size_t length,
    65                                               const uint8_t *whole_pdu, size_t pdu_length,
    66                                               enum ntlmssp_direction direction,
    67                                               DATA_BLOB *sig, bool encrypt_sig)
    68 {
    69         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    70 
    71                 HMACMD5Context ctx;
    72                 uint8_t digest[16];
    73                 uint8_t seq_num[4];
    74 
    75                 *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE);
    76                 if (!sig->data) {
    77                         return NT_STATUS_NO_MEMORY;
    78                 }
    79                        
    80                 switch (direction) {
    81                 case NTLMSSP_SEND:
    82                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.send_seq_num);
    83                         gensec_ntlmssp_state->crypt.ntlm2.send_seq_num++;
    84                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data,
    85                                                  gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length, &ctx);
    86                         break;
    87                 case NTLMSSP_RECEIVE:
    88                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num);
    89                         gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num++;
    90                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    91                                                  gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length, &ctx);
    92                         break;
    93                 }
    94                 hmac_md5_update(seq_num, sizeof(seq_num), &ctx);
    95                 hmac_md5_update(whole_pdu, pdu_length, &ctx);
    96                 hmac_md5_final(digest, &ctx);
    97 
    98                 if (encrypt_sig && gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    99                         switch (direction) {
    100                         case NTLMSSP_SEND:
    101                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, digest, 8);
    102                                 break;
    103                         case NTLMSSP_RECEIVE:
    104                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, digest, 8);
    105                                 break;
    106                         }
    107                 }
    108 
    109                 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
    110                 memcpy(sig->data + 4, digest, 8);
    111                 memcpy(sig->data + 12, seq_num, 4);
    112 
    113                 DEBUG(10, ("NTLM2: created signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    114                 dump_data(11, sig->data, sig->length);
    115                        
    116         } else {
    117                 uint32_t crc;
    118                 crc = crc32_calc_buffer(data, length);
    119                 if (!msrpc_gen(sig_mem_ctx,
    120                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
    121                         return NT_STATUS_NO_MEMORY;
    122                 }
    123                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
    124 
    125                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
    126 
    127                 DEBUG(10, ("NTLM1: created signature over %llu bytes of input:\n", (unsigned long long)length));
    128                 dump_data(11, sig->data, sig->length);
    129         }
    130         return NT_STATUS_OK;
    131 }
    132 
    133 /* TODO: make this non-public */
    134 NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
    135                                     TALLOC_CTX *sig_mem_ctx,
    136                                     const uint8_t *data, size_t length,
    137                                     const uint8_t *whole_pdu, size_t pdu_length,
     27NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
     28                                    TALLOC_CTX *sig_mem_ctx,
     29                                    const uint8_t *data, size_t length,
     30                                    const uint8_t *whole_pdu, size_t pdu_length,
    13831                                    DATA_BLOB *sig)
    13932{
    140         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    141 
    142         return ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    143                                              data, length,
    144                                              whole_pdu, pdu_length,
    145                                              NTLMSSP_SEND, sig, true);
    146 }
    147 
    148 /**
    149  * Check the signature of an incoming packet
    150  *
    151  */
    152 
    153 NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
    154                                      TALLOC_CTX *sig_mem_ctx,
    155                                      const uint8_t *data, size_t length,
    156                                      const uint8_t *whole_pdu, size_t pdu_length,
    157                                      const DATA_BLOB *sig)
    158 {
    159         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    160 
    161         DATA_BLOB local_sig;
     33        struct gensec_ntlmssp_context *gensec_ntlmssp =
     34                talloc_get_type_abort(gensec_security->private_data,
     35                                      struct gensec_ntlmssp_context);
    16236        NTSTATUS nt_status;
    16337
    164         if (!gensec_ntlmssp_state->session_key.length) {
    165                 DEBUG(3, ("NO session key, cannot check packet signature\n"));
    166                 return NT_STATUS_NO_USER_SESSION_KEY;
    167         }
    168 
    169         nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    170                                                   data, length,
    171                                                   whole_pdu, pdu_length,
    172                                                   NTLMSSP_RECEIVE, &local_sig, true);
    173        
    174         if (!NT_STATUS_IS_OK(nt_status)) {
    175                 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
    176                 return nt_status;
    177         }
    178 
    179         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    180                 if (local_sig.length != sig->length ||
    181                     memcmp(local_sig.data,
    182                            sig->data, sig->length) != 0) {
    183                         DEBUG(5, ("BAD SIG NTLM2: wanted signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    184                         dump_data(5, local_sig.data, local_sig.length);
    185                        
    186                         DEBUG(5, ("BAD SIG: got signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    187                         dump_data(5, sig->data, sig->length);
    188                        
    189                         DEBUG(1, ("NTLMSSP NTLM2 packet check failed due to invalid signature on %llu bytes of input!\n", (unsigned long long)pdu_length));
    190                         return NT_STATUS_ACCESS_DENIED;
    191                 }
    192         } else {
    193                 if (local_sig.length != sig->length ||
    194                     memcmp(local_sig.data + 8,
    195                            sig->data + 8, sig->length - 8) != 0) {
    196                         DEBUG(5, ("BAD SIG NTLM1: wanted signature of %llu bytes of input:\n", (unsigned long long)length));
    197                         dump_data(5, local_sig.data, local_sig.length);
    198                        
    199                         DEBUG(5, ("BAD SIG: got signature of %llu bytes of input:\n", (unsigned long long)length));
    200                         dump_data(5, sig->data, sig->length);
    201                        
    202                         DEBUG(1, ("NTLMSSP NTLM1 packet check failed due to invalid signature on %llu bytes of input:\n", (unsigned long long)length));
    203                         return NT_STATUS_ACCESS_DENIED;
    204                 }
    205         }
    206         dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
    207 
    208         return NT_STATUS_OK;
    209 }
    210 
    211 
    212 /**
    213  * Seal data with the NTLMSSP algorithm
    214  *
    215  */
    216 
    217 NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
    218                                     TALLOC_CTX *sig_mem_ctx,
    219                                     uint8_t *data, size_t length,
    220                                     const uint8_t *whole_pdu, size_t pdu_length,
    221                                     DATA_BLOB *sig)
    222 {
    223         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    224         NTSTATUS nt_status;
    225         if (!gensec_ntlmssp_state->session_key.length) {
    226                 DEBUG(3, ("NO session key, cannot seal packet\n"));
    227                 return NT_STATUS_NO_USER_SESSION_KEY;
    228         }
    229 
    230         DEBUG(10,("ntlmssp_seal_data: seal\n"));
    231         dump_data_pw("ntlmssp clear data\n", data, length);
    232         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    233                 /* The order of these two operations matters - we must first seal the packet,
    234                    then seal the sequence number - this is becouse the send_seal_hash is not
    235                    constant, but is is rather updated with each iteration */
    236                 nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    237                                                           data, length,
    238                                                           whole_pdu, pdu_length,
    239                                                           NTLMSSP_SEND, sig, false);
    240                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, data, length);
    241                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    242                         arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, sig->data+4, 8);
    243                 }
    244         } else {
    245                 uint32_t crc;
    246                 crc = crc32_calc_buffer(data, length);
    247                 if (!msrpc_gen(sig_mem_ctx,
    248                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
    249                         return NT_STATUS_NO_MEMORY;
    250                 }
    251 
    252                 /* The order of these two operations matters - we must
    253                    first seal the packet, then seal the sequence
    254                    number - this is becouse the ntlmssp_hash is not
    255                    constant, but is is rather updated with each
    256                    iteration */
    257 
    258                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
    259                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
    260                 /* increment counter on send */
    261                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
    262                 nt_status = NT_STATUS_OK;
    263         }
    264         dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
    265         dump_data_pw("ntlmssp sealed data\n", data, length);
    266 
     38        nt_status = ntlmssp_sign_packet(gensec_ntlmssp->ntlmssp_state,
     39                                        sig_mem_ctx,
     40                                        data, length,
     41                                        whole_pdu, pdu_length,
     42                                        sig);
    26743
    26844        return nt_status;
    26945}
    27046
    271 /**
    272  * Unseal data with the NTLMSSP algorithm
    273  *
    274  */
     47NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
     48                                     TALLOC_CTX *sig_mem_ctx,
     49                                     const uint8_t *data, size_t length,
     50                                     const uint8_t *whole_pdu, size_t pdu_length,
     51                                     const DATA_BLOB *sig)
     52{
     53        struct gensec_ntlmssp_context *gensec_ntlmssp =
     54                talloc_get_type_abort(gensec_security->private_data,
     55                                      struct gensec_ntlmssp_context);
     56        NTSTATUS nt_status;
     57
     58        nt_status = ntlmssp_check_packet(gensec_ntlmssp->ntlmssp_state,
     59                                         data, length,
     60                                         whole_pdu, pdu_length,
     61                                         sig);
     62
     63        return nt_status;
     64}
     65
     66NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
     67                                    TALLOC_CTX *sig_mem_ctx,
     68                                    uint8_t *data, size_t length,
     69                                    const uint8_t *whole_pdu, size_t pdu_length,
     70                                    DATA_BLOB *sig)
     71{
     72        struct gensec_ntlmssp_context *gensec_ntlmssp =
     73                talloc_get_type_abort(gensec_security->private_data,
     74                                      struct gensec_ntlmssp_context);
     75        NTSTATUS nt_status;
     76
     77        nt_status = ntlmssp_seal_packet(gensec_ntlmssp->ntlmssp_state,
     78                                        sig_mem_ctx,
     79                                        data, length,
     80                                        whole_pdu, pdu_length,
     81                                        sig);
     82
     83        return nt_status;
     84}
    27585
    27686/*
    27787  wrappers for the ntlmssp_*() functions
    27888*/
    279 NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, 
    280                                       TALLOC_CTX *sig_mem_ctx, 
    281                                       uint8_t *data, size_t length, 
    282                                       const uint8_t *whole_pdu, size_t pdu_length, 
     89NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
     90                                      TALLOC_CTX *sig_mem_ctx,
     91                                      uint8_t *data, size_t length,
     92                                      const uint8_t *whole_pdu, size_t pdu_length,
    28393                                      const DATA_BLOB *sig)
    28494{
    285         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    286         if (!gensec_ntlmssp_state->session_key.length) {
    287                 DEBUG(3, ("NO session key, cannot unseal packet\n"));
    288                 return NT_STATUS_NO_USER_SESSION_KEY;
    289         }
     95        struct gensec_ntlmssp_context *gensec_ntlmssp =
     96                talloc_get_type_abort(gensec_security->private_data,
     97                                      struct gensec_ntlmssp_context);
     98        NTSTATUS nt_status;
    29099
    291         dump_data_pw("ntlmssp sealed data\n", data, length);
    292         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    293                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, data, length);
    294         } else {
    295                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
    296         }
    297         dump_data_pw("ntlmssp clear data\n", data, length);
    298         return gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
    299 }
     100        nt_status = ntlmssp_unseal_packet(gensec_ntlmssp->ntlmssp_state,
     101                                          data, length,
     102                                          whole_pdu, pdu_length,
     103                                          sig);
    300104
    301 /**
    302    Initialise the state for NTLMSSP signing.
    303 */
    304 /* TODO: make this non-public */
    305 NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    306 {
    307         TALLOC_CTX *mem_ctx = talloc_new(gensec_ntlmssp_state);
    308 
    309         if (!mem_ctx) {
    310                 return NT_STATUS_NO_MEMORY;
    311         }
    312 
    313         DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
    314         debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
    315 
    316         if (gensec_ntlmssp_state->session_key.length < 8) {
    317                 talloc_free(mem_ctx);
    318                 DEBUG(3, ("NO session key, cannot intialise signing\n"));
    319                 return NT_STATUS_NO_USER_SESSION_KEY;
    320         }
    321 
    322         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
    323         {
    324                 DATA_BLOB weak_session_key = gensec_ntlmssp_state->session_key;
    325                 const char *send_sign_const;
    326                 const char *send_seal_const;
    327                 const char *recv_sign_const;
    328                 const char *recv_seal_const;
    329 
    330                 DATA_BLOB send_seal_key;
    331                 DATA_BLOB recv_seal_key;
    332 
    333                 switch (gensec_ntlmssp_state->role) {
    334                 case NTLMSSP_CLIENT:
    335                         send_sign_const = CLI_SIGN;
    336                         send_seal_const = CLI_SEAL;
    337                         recv_sign_const = SRV_SIGN;
    338                         recv_seal_const = SRV_SEAL;
    339                         break;
    340                 case NTLMSSP_SERVER:
    341                         send_sign_const = SRV_SIGN;
    342                         send_seal_const = SRV_SEAL;
    343                         recv_sign_const = CLI_SIGN;
    344                         recv_seal_const = CLI_SEAL;
    345                         break;
    346                 default:
    347                         talloc_free(mem_ctx);
    348                         return NT_STATUS_INTERNAL_ERROR;
    349                 }
    350                
    351                 gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    352                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
    353                 gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    354                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
    355 
    356                 /**
    357                    Weaken NTLMSSP keys to cope with down-level
    358                    clients, servers and export restrictions.
    359                    
    360                    We probably should have some parameters to control
    361                    this, once we get NTLM2 working.
    362                 */
    363 
    364                 /* Key weakening was not performed on the master key
    365                  * for NTLM2 (in ntlmssp_weaken_keys()), but must be
    366                  * done on the encryption subkeys only.  That is why
    367                  * we don't have this code for the ntlmv1 case.
    368                  */
    369 
    370                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
    371                        
    372                 } else if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
    373                         weak_session_key.length = 7;
    374                 } else { /* forty bits */
    375                         weak_session_key.length = 5;
    376                 }
    377                 dump_data_pw("NTLMSSP weakend master key:\n",
    378                              weak_session_key.data,
    379                              weak_session_key.length);
    380 
    381                 /* SEND: sign key */
    382                 calc_ntlmv2_key(gensec_ntlmssp_state,
    383                                 &gensec_ntlmssp_state->crypt.ntlm2.send_sign_key,
    384                                 gensec_ntlmssp_state->session_key, send_sign_const);
    385                 dump_data_pw("NTLMSSP send sign key:\n",
    386                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data,
    387                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length);
    388                
    389                 /* SEND: seal ARCFOUR pad */
    390                 calc_ntlmv2_key(mem_ctx,
    391                                 &send_seal_key,
    392                                 weak_session_key, send_seal_const);
    393                 dump_data_pw("NTLMSSP send seal key:\n",
    394                              send_seal_key.data,
    395                              send_seal_key.length);
    396                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state,
    397                              &send_seal_key);
    398                 dump_data_pw("NTLMSSP send sesl hash:\n",
    399                              gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox,
    400                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox));
    401 
    402                 /* RECV: sign key */
    403                 calc_ntlmv2_key(gensec_ntlmssp_state,
    404                                 &gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key,
    405                                 gensec_ntlmssp_state->session_key, recv_sign_const);
    406                 dump_data_pw("NTLMSSP recv sign key:\n",
    407                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    408                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length);
    409 
    410                 /* RECV: seal ARCFOUR pad */
    411                 calc_ntlmv2_key(mem_ctx,
    412                                 &recv_seal_key,
    413                                 weak_session_key, recv_seal_const);
    414                 dump_data_pw("NTLMSSP recv seal key:\n",
    415                              recv_seal_key.data,
    416                              recv_seal_key.length);
    417                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state,
    418                              &recv_seal_key);
    419                 dump_data_pw("NTLMSSP receive seal hash:\n",
    420                              gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox,
    421                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox));
    422 
    423                 gensec_ntlmssp_state->crypt.ntlm2.send_seq_num = 0;
    424                 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = 0;
    425 
    426         } else {
    427                 DATA_BLOB weak_session_key = ntlmssp_weakend_key(gensec_ntlmssp_state, mem_ctx);
    428                 DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
    429 
    430                 gensec_ntlmssp_state->crypt.ntlm.arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    431                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm.arcfour_state);
    432 
    433                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm.arcfour_state,
    434                              &weak_session_key);
    435                 dump_data_pw("NTLMSSP hash:\n", gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox,
    436                              sizeof(gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox));
    437 
    438                 gensec_ntlmssp_state->crypt.ntlm.seq_num = 0;
    439         }
    440 
    441         talloc_free(mem_ctx);
    442         return NT_STATUS_OK;
     105        return nt_status;
    443106}
    444107
     
    449112
    450113NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security,
    451                              TALLOC_CTX *sig_mem_ctx,
     114                             TALLOC_CTX *out_mem_ctx,
    452115                             const DATA_BLOB *in,
    453116                             DATA_BLOB *out)
    454117{
    455         DATA_BLOB sig;
    456         NTSTATUS nt_status;
     118        struct gensec_ntlmssp_context *gensec_ntlmssp =
     119                talloc_get_type_abort(gensec_security->private_data,
     120                                      struct gensec_ntlmssp_context);
    457121
    458         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    459 
    460                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
    461                 if (!out->data) {
    462                         return NT_STATUS_NO_MEMORY;
    463                 }
    464                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
    465                
    466                 nt_status = gensec_ntlmssp_seal_packet(gensec_security, sig_mem_ctx,
    467                                                        out->data + NTLMSSP_SIG_SIZE,
    468                                                        out->length - NTLMSSP_SIG_SIZE,
    469                                                        out->data + NTLMSSP_SIG_SIZE,
    470                                                        out->length - NTLMSSP_SIG_SIZE,
    471                                                        &sig);
    472                
    473                 if (NT_STATUS_IS_OK(nt_status)) {
    474                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
    475                 }
    476                 return nt_status;
    477 
    478         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    479 
    480                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
    481                 if (!out->data) {
    482                         return NT_STATUS_NO_MEMORY;
    483                 }
    484                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
    485 
    486                 nt_status = gensec_ntlmssp_sign_packet(gensec_security, sig_mem_ctx,
    487                                                        out->data + NTLMSSP_SIG_SIZE,
    488                                                        out->length - NTLMSSP_SIG_SIZE,
    489                                                        out->data + NTLMSSP_SIG_SIZE,
    490                                                        out->length - NTLMSSP_SIG_SIZE,
    491                                                        &sig);
    492 
    493                 if (NT_STATUS_IS_OK(nt_status)) {
    494                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
    495                 }
    496                 return nt_status;
    497 
    498         } else {
    499                 *out = *in;
    500                 return NT_STATUS_OK;
    501         }
     122        return ntlmssp_wrap(gensec_ntlmssp->ntlmssp_state,
     123                            out_mem_ctx,
     124                            in, out);
    502125}
    503126
    504127
    505128NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security,
    506                                TALLOC_CTX *sig_mem_ctx,
     129                               TALLOC_CTX *out_mem_ctx,
    507130                               const DATA_BLOB *in,
    508131                               DATA_BLOB *out)
    509132{
    510         DATA_BLOB sig;
     133        struct gensec_ntlmssp_context *gensec_ntlmssp =
     134                talloc_get_type_abort(gensec_security->private_data,
     135                                      struct gensec_ntlmssp_context);
    511136
    512         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    513                 if (in->length < NTLMSSP_SIG_SIZE) {
    514                         return NT_STATUS_INVALID_PARAMETER;
    515                 }
    516                 sig.data = in->data;
    517                 sig.length = NTLMSSP_SIG_SIZE;
    518 
    519                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
    520                
    521                 return gensec_ntlmssp_unseal_packet(gensec_security, sig_mem_ctx,
    522                                                     out->data, out->length,
    523                                                     out->data, out->length,
    524                                                     &sig);
    525                                                  
    526         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    527                 struct gensec_ntlmssp_state *gensec_ntlmssp_state =
    528                 (struct gensec_ntlmssp_state *)gensec_security->private_data;
    529                 NTSTATUS status;
    530                 uint32_t ntlm_seqnum;
    531                 struct arcfour_state ntlm_state;
    532                 uint32_t ntlm2_seqnum_r;
    533                 uint8_t ntlm2_key_r[16];
    534                 struct arcfour_state ntlm2_state_r;
    535 
    536                 if (in->length < NTLMSSP_SIG_SIZE) {
    537                         return NT_STATUS_INVALID_PARAMETER;
    538                 }
    539                 sig.data = in->data;
    540                 sig.length = NTLMSSP_SIG_SIZE;
    541                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
    542 
    543                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    544                         ntlm2_seqnum_r = gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num;
    545                         ntlm2_state_r = *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state;
    546                         memcpy(ntlm2_key_r,
    547                                gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    548                                16);
    549                 } else {
    550                         ntlm_seqnum = gensec_ntlmssp_state->crypt.ntlm.seq_num;
    551                         ntlm_state = *gensec_ntlmssp_state->crypt.ntlm.arcfour_state;
    552                 }
    553 
    554                 status = gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx,
    555                                                      out->data, out->length,
    556                                                      out->data, out->length,
    557                                                      &sig);
    558                 if (!NT_STATUS_IS_OK(status)) {
    559                         NTSTATUS check_status = status;
    560                         /*
    561                          * The Windows LDAP libraries seems to have a bug
    562                          * and always use sealing even if only signing was
    563                          * negotiated. So we need to fallback.
    564                          */
    565 
    566                         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    567                                 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = ntlm2_seqnum_r;
    568                                 *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = ntlm2_state_r;
    569                                 memcpy(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    570                                        ntlm2_key_r, 16);
    571                         } else {
    572                                 gensec_ntlmssp_state->crypt.ntlm.seq_num = ntlm_seqnum;
    573                                 *gensec_ntlmssp_state->crypt.ntlm.arcfour_state = ntlm_state;
    574                         }
    575 
    576                         status = gensec_ntlmssp_unseal_packet(gensec_security,
    577                                                               sig_mem_ctx,
    578                                                               out->data,
    579                                                               out->length,
    580                                                               out->data,
    581                                                               out->length,
    582                                                               &sig);
    583                         if (NT_STATUS_IS_OK(status)) {
    584                                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    585                         } else {
    586                                 status = check_status;
    587                         }
    588                 }
    589                 return status;
    590         } else {
    591                 *out = *in;
    592                 return NT_STATUS_OK;
    593         }
     137        return ntlmssp_unwrap(gensec_ntlmssp->ntlmssp_state,
     138                              out_mem_ctx,
     139                              in, out);
    594140}
    595 
  • vendor/current/source4/auth/pyauth.c

    r414 r740  
    22   Unix SMB/CIFS implementation.
    33   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
    4    
     4   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2011
     5
    56   This program is free software; you can redistribute it and/or modify
    67   it under the terms of the GNU General Public License as published by
     
    1718*/
    1819
     20#include <Python.h>
    1921#include "includes.h"
     22#include "libcli/util/pyerrors.h"
    2023#include "param/param.h"
    2124#include "pyauth.h"
     25#include "pyldb.h"
    2226#include "auth/system_session_proto.h"
     27#include "auth/auth.h"
    2328#include "param/pyparam.h"
    2429#include "libcli/security/security.h"
    25 
    26 
    27 PyTypeObject PyAuthSession = {
     30#include "auth/credentials/pycredentials.h"
     31#include <tevent.h>
     32#include "librpc/rpc/pyrpc_util.h"
     33
     34staticforward PyTypeObject PyAuthContext;
     35
     36/* There's no Py_ssize_t in 2.4, apparently */
     37#if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5
     38typedef int Py_ssize_t;
     39typedef inquiry lenfunc;
     40typedef intargfunc ssizeargfunc;
     41#endif
     42
     43#ifndef Py_RETURN_NONE
     44#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
     45#endif
     46
     47static PyObject *py_auth_session_get_security_token(PyObject *self, void *closure)
     48{
     49        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     50        PyObject *py_security_token;
     51        py_security_token = py_return_ndr_struct("samba.dcerpc.security", "token",
     52                                                 session->security_token, session->security_token);
     53        return py_security_token;
     54}
     55
     56static int py_auth_session_set_security_token(PyObject *self, PyObject *value, void *closure)
     57{
     58        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     59        session->security_token = talloc_reference(session, py_talloc_get_ptr(value));
     60        return 0;
     61}
     62
     63static PyObject *py_auth_session_get_session_key(PyObject *self, void *closure)
     64{
     65        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     66        return PyString_FromStringAndSize((char *)session->session_key.data, session->session_key.length);
     67}
     68
     69static int py_auth_session_set_session_key(PyObject *self, PyObject *value, void *closure)
     70{
     71        DATA_BLOB val;
     72        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     73        val.data = (uint8_t *)PyString_AsString(value);
     74        val.length = PyString_Size(value);
     75
     76        session->session_key = data_blob_talloc(session, val.data, val.length);
     77        return 0;
     78}
     79
     80static PyObject *py_auth_session_get_credentials(PyObject *self, void *closure)
     81{
     82        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     83        PyObject *py_credentials;
     84        /* This is evil, as the credentials are not IDL structures */
     85        py_credentials = py_return_ndr_struct("samba.credentials", "Credentials", session->credentials, session->credentials);
     86        return py_credentials;
     87}
     88
     89static int py_auth_session_set_credentials(PyObject *self, PyObject *value, void *closure)
     90{
     91        struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info);
     92        session->credentials = talloc_reference(session, PyCredentials_AsCliCredentials(value));
     93        return 0;
     94}
     95
     96static PyGetSetDef py_auth_session_getset[] = {
     97        { discard_const_p(char, "security_token"), (getter)py_auth_session_get_security_token, (setter)py_auth_session_set_security_token, NULL },
     98        { discard_const_p(char, "session_key"), (getter)py_auth_session_get_session_key, (setter)py_auth_session_set_session_key, NULL },
     99        { discard_const_p(char, "credentials"), (getter)py_auth_session_get_credentials, (setter)py_auth_session_set_credentials, NULL },
     100        { NULL }
     101};
     102
     103static PyTypeObject PyAuthSession = {
    28104        .tp_name = "AuthSession",
    29105        .tp_basicsize = sizeof(py_talloc_Object),
    30         .tp_dealloc = py_talloc_dealloc,
    31106        .tp_flags = Py_TPFLAGS_DEFAULT,
    32         .tp_repr = py_talloc_default_repr,
     107        .tp_getset = py_auth_session_getset,
    33108};
    34109
     
    43118        struct loadparm_context *lp_ctx = NULL;
    44119        struct auth_session_info *session;
     120        TALLOC_CTX *mem_ctx;
    45121        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    46122                return NULL;
    47123
    48         lp_ctx = lp_from_py_object(py_lp_ctx);
    49         if (lp_ctx == NULL)
    50                 return NULL;
    51 
    52         session = system_session(NULL, lp_ctx);
     124        mem_ctx = talloc_new(NULL);
     125        if (mem_ctx == NULL) {
     126                PyErr_NoMemory();
     127                return NULL;
     128        }
     129
     130        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     131        if (lp_ctx == NULL) {
     132                talloc_free(mem_ctx);
     133                return NULL;
     134        }
     135
     136        session = system_session(lp_ctx);
     137
     138        talloc_free(mem_ctx);
    53139
    54140        return PyAuthSession_FromSession(session);
    55141}
    56142
    57 
    58 static PyObject *py_system_session_anon(PyObject *module, PyObject *args)
    59 {
    60         PyObject *py_lp_ctx = Py_None;
    61         struct loadparm_context *lp_ctx;
    62         struct auth_session_info *session;
    63         if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    64                 return NULL;
    65 
    66         lp_ctx = lp_from_py_object(py_lp_ctx);
    67         if (lp_ctx == NULL)
    68                 return NULL;
    69 
    70         session = system_session_anon(NULL, lp_ctx);
    71 
    72         return PyAuthSession_FromSession(session);
    73 }
    74143
    75144static PyObject *py_admin_session(PyObject *module, PyObject *args)
     
    80149        struct auth_session_info *session;
    81150        struct dom_sid *domain_sid = NULL;
     151        TALLOC_CTX *mem_ctx;
     152
    82153        if (!PyArg_ParseTuple(args, "OO", &py_lp_ctx, &py_sid))
    83154                return NULL;
    84155
    85         lp_ctx = lp_from_py_object(py_lp_ctx);
    86         if (lp_ctx == NULL)
    87                 return NULL;
    88 
    89         domain_sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid));
     156        mem_ctx = talloc_new(NULL);
     157        if (mem_ctx == NULL) {
     158                PyErr_NoMemory();
     159                return NULL;
     160        }
     161
     162        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     163        if (lp_ctx == NULL) {
     164                talloc_free(mem_ctx);
     165                return NULL;
     166        }
     167
     168        domain_sid = dom_sid_parse_talloc(mem_ctx, PyString_AsString(py_sid));
     169        if (domain_sid == NULL) {
     170                PyErr_Format(PyExc_RuntimeError, "Unable to parse sid %s",
     171                                         PyString_AsString(py_sid));
     172                talloc_free(mem_ctx);
     173                return NULL;
     174        }
    90175        session = admin_session(NULL, lp_ctx, domain_sid);
     176        talloc_free(mem_ctx);
    91177
    92178        return PyAuthSession_FromSession(session);
    93179}
     180
     181static PyObject *py_user_session(PyObject *module, PyObject *args, PyObject *kwargs)
     182{
     183        NTSTATUS nt_status;
     184        struct auth_session_info *session;
     185        TALLOC_CTX *mem_ctx;
     186        const char * const kwnames[] = { "ldb", "lp_ctx", "principal", "dn", "session_info_flags", NULL };
     187        struct ldb_context *ldb_ctx;
     188        PyObject *py_ldb = Py_None;
     189        PyObject *py_dn = Py_None;
     190        PyObject *py_lp_ctx = Py_None;
     191        struct loadparm_context *lp_ctx = NULL;
     192        struct ldb_dn *user_dn;
     193        char *principal = NULL;
     194        int session_info_flags = 0; /* This is an int, because that's
     195                                 * what we need for the python
     196                                 * PyArg_ParseTupleAndKeywords */
     197
     198        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OzOi",
     199                                         discard_const_p(char *, kwnames),
     200                                         &py_ldb, &py_lp_ctx, &principal, &py_dn, &session_info_flags)) {
     201                return NULL;
     202        }
     203
     204        mem_ctx = talloc_new(NULL);
     205        if (mem_ctx == NULL) {
     206                PyErr_NoMemory();
     207                return NULL;
     208        }
     209
     210        ldb_ctx = PyLdb_AsLdbContext(py_ldb);
     211
     212        if (py_dn == Py_None) {
     213                user_dn = NULL;
     214        } else {
     215                if (!PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) {
     216                        talloc_free(mem_ctx);
     217                        return NULL;
     218                }
     219        }
     220
     221        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     222        if (lp_ctx == NULL) {
     223                talloc_free(mem_ctx);
     224                return NULL;
     225        }
     226
     227        nt_status = authsam_get_session_info_principal(mem_ctx, lp_ctx, ldb_ctx, principal, user_dn,
     228                                                       session_info_flags, &session);
     229        if (!NT_STATUS_IS_OK(nt_status)) {
     230                talloc_free(mem_ctx);
     231                PyErr_NTSTATUS_IS_ERR_RAISE(nt_status);
     232        }
     233
     234        talloc_steal(NULL, session);
     235        talloc_free(mem_ctx);
     236
     237        return PyAuthSession_FromSession(session);
     238}
     239
     240
     241static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list,
     242                                        const char *paramname)
     243{
     244        const char **ret;
     245        Py_ssize_t i;
     246        if (!PyList_Check(list)) {
     247                PyErr_Format(PyExc_TypeError, "%s is not a list", paramname);
     248                return NULL;
     249        }
     250        ret = talloc_array(NULL, const char *, PyList_Size(list)+1);
     251        if (ret == NULL) {
     252                PyErr_NoMemory();
     253                return NULL;
     254        }
     255
     256        for (i = 0; i < PyList_Size(list); i++) {
     257                PyObject *item = PyList_GetItem(list, i);
     258                if (!PyString_Check(item)) {
     259                        PyErr_Format(PyExc_TypeError, "%s should be strings", paramname);
     260                        return NULL;
     261                }
     262                ret[i] = talloc_strndup(ret, PyString_AsString(item),
     263                                        PyString_Size(item));
     264        }
     265        ret[i] = NULL;
     266        return ret;
     267}
     268
     269static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context)
     270{
     271        return py_talloc_reference(&PyAuthContext, auth_context);
     272}
     273
     274static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     275{
     276        PyObject *py_lp_ctx = Py_None;
     277        PyObject *py_ldb = Py_None;
     278        PyObject *py_messaging_ctx = Py_None;
     279        PyObject *py_auth_context = Py_None;
     280        PyObject *py_methods = Py_None;
     281        TALLOC_CTX *mem_ctx;
     282        struct auth_context *auth_context;
     283        struct messaging_context *messaging_context = NULL;
     284        struct loadparm_context *lp_ctx;
     285        struct tevent_context *ev;
     286        struct ldb_context *ldb;
     287        NTSTATUS nt_status;
     288        const char **methods;
     289
     290        const char * const kwnames[] = { "lp_ctx", "messaging_ctx", "ldb", "methods", NULL };
     291
     292        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO",
     293                                         discard_const_p(char *, kwnames),
     294                                         &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods))
     295                return NULL;
     296
     297        mem_ctx = talloc_new(NULL);
     298        if (mem_ctx == NULL) {
     299                PyErr_NoMemory();
     300                return NULL;
     301        }
     302
     303        if (py_ldb != Py_None) {
     304                ldb = PyLdb_AsLdbContext(py_ldb);
     305        }
     306
     307        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     308
     309        ev = tevent_context_init(mem_ctx);
     310        if (ev == NULL) {
     311                PyErr_NoMemory();
     312                return NULL;
     313        }
     314
     315        if (py_messaging_ctx != Py_None) {
     316                messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context);
     317        }
     318
     319        if (py_methods == Py_None && py_ldb == Py_None) {
     320                nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context);
     321        } else {
     322                if (py_methods != Py_None) {
     323                        methods = PyList_AsStringList(mem_ctx, py_methods, "methods");
     324                        if (methods == NULL) {
     325                                talloc_free(mem_ctx);
     326                                return NULL;
     327                        }
     328                } else {
     329                        methods = auth_methods_from_lp(mem_ctx, lp_ctx);
     330                }
     331                nt_status = auth_context_create_methods(mem_ctx, methods, ev,
     332                                                        messaging_context, lp_ctx,
     333                                                        ldb, &auth_context);
     334        }
     335
     336        if (!NT_STATUS_IS_OK(nt_status)) {
     337                talloc_free(mem_ctx);
     338                PyErr_NTSTATUS_IS_ERR_RAISE(nt_status);
     339        }
     340
     341        if (!talloc_reference(auth_context, lp_ctx)) {
     342                talloc_free(mem_ctx);
     343                PyErr_NoMemory();
     344                return NULL;
     345        }
     346
     347        if (!talloc_reference(auth_context, ev)) {
     348                talloc_free(mem_ctx);
     349                PyErr_NoMemory();
     350                return NULL;
     351        }
     352
     353        py_auth_context = PyAuthContext_FromContext(auth_context);
     354
     355        talloc_free(mem_ctx);
     356
     357        return py_auth_context;
     358}
     359
     360static PyTypeObject PyAuthContext = {
     361        .tp_name = "AuthContext",
     362        .tp_basicsize = sizeof(py_talloc_Object),
     363        .tp_flags = Py_TPFLAGS_DEFAULT,
     364        .tp_new = py_auth_context_new,
     365        .tp_basicsize = sizeof(py_talloc_Object),
     366};
    94367
    95368static PyMethodDef py_auth_methods[] = {
    96369        { "system_session", (PyCFunction)py_system_session, METH_VARARGS, NULL },
    97         { "system_session_anonymous", (PyCFunction)py_system_session_anon, METH_VARARGS, NULL },
    98370        { "admin_session", (PyCFunction)py_admin_session, METH_VARARGS, NULL },
     371        { "user_session", (PyCFunction)py_user_session, METH_VARARGS|METH_KEYWORDS, NULL },
    99372        { NULL },
    100373};
     
    104377        PyObject *m;
    105378
     379        PyAuthSession.tp_base = PyTalloc_GetObjectType();
     380        if (PyAuthSession.tp_base == NULL)
     381                return;
     382
    106383        if (PyType_Ready(&PyAuthSession) < 0)
    107384                return;
    108385
    109         m = Py_InitModule3("auth", py_auth_methods, "Authentication and authorization support.");
     386        PyAuthContext.tp_base = PyTalloc_GetObjectType();
     387        if (PyAuthContext.tp_base == NULL)
     388                return;
     389
     390        if (PyType_Ready(&PyAuthContext) < 0)
     391                return;
     392
     393        m = Py_InitModule3("auth", py_auth_methods,
     394                                           "Authentication and authorization support.");
    110395        if (m == NULL)
    111396                return;
     
    113398        Py_INCREF(&PyAuthSession);
    114399        PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession);
    115 }
     400        Py_INCREF(&PyAuthContext);
     401        PyModule_AddObject(m, "AuthContext", (PyObject *)&PyAuthContext);
     402
     403#define ADD_FLAG(val)  PyModule_AddObject(m, #val, PyInt_FromLong(val))
     404        ADD_FLAG(AUTH_SESSION_INFO_DEFAULT_GROUPS);
     405        ADD_FLAG(AUTH_SESSION_INFO_AUTHENTICATED);
     406        ADD_FLAG(AUTH_SESSION_INFO_SIMPLE_PRIVILEGES);
     407
     408}
  • vendor/current/source4/auth/pyauth.h

    r414 r740  
    2121#define _PYAUTH_H_
    2222
    23 #include "pytalloc.h"
     23#include <pytalloc.h>
    2424#include "auth/session.h"
    2525
    26 PyAPI_DATA(PyTypeObject) PyAuthSession;
    2726#define PyAuthSession_AsSession(obj) py_talloc_get_type(obj, struct auth_session_info)
    2827#define PyAuthSession_Check(obj) PyObject_TypeCheck(obj, &PyAuthSession)
  • vendor/current/source4/auth/sam.c

    r414 r740  
    22   Unix SMB/CIFS implementation.
    33   Password and authentication handling
    4    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2004
     4   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2010
    55   Copyright (C) Gerald Carter                             2003
    66   Copyright (C) Stefan Metzmacher                         2005
     
    2525#include "auth/auth.h"
    2626#include <ldb.h>
    27 #include "../lib/util/util_ldb.h"
    2827#include "dsdb/samdb/samdb.h"
    2928#include "libcli/security/security.h"
    30 #include "libcli/ldap/ldap.h"
    31 #include "../libcli/ldap/ldap_ndr.h"
    32 #include "librpc/gen_ndr/ndr_netlogon.h"
    33 #include "librpc/gen_ndr/ndr_security.h"
     29#include "auth/auth_sam.h"
     30#include "dsdb/common/util.h"
     31#include "libcli/ldap/ldap_ndr.h"
    3432#include "param/param.h"
    35 #include "auth/auth_sam.h"
    3633
    3734#define KRBTGT_ATTRS \
     
    4239        "servicePrincipalName",                 \
    4340        "msDS-KeyVersionNumber",                \
     41        "msDS-SecondaryKrbTgtNumber",           \
     42        "msDS-SupportedEncryptionTypes",        \
    4443        "supplementalCredentials",              \
    4544                                                \
     
    5251                                                \
    5352        "pwdLastSet",                           \
    54         "accountExpires"                       
     53        "accountExpires"
    5554
    5655const char *krbtgt_attrs[] = {
    57         KRBTGT_ATTRS
     56        KRBTGT_ATTRS, NULL
    5857};
    5958
    6059const char *server_attrs[] = {
    61         KRBTGT_ATTRS
     60        KRBTGT_ATTRS, NULL
    6261};
    6362
     
    7069        "userWorkstations",
    7170                       
    72         /* required for server_info, not access control: */
     71        /* required for user_info_dc, not access control: */
    7372        "displayName",
    7473        "scriptPath",
     
    149148
    150149/****************************************************************************
    151  Do a specific test for a SAM_ACCOUNT being vaild for this connection
     150 Do a specific test for a SAM_ACCOUNT being valid for this connection
    152151 (ie not disabled, expired and the like).
    153152****************************************************************************/
     
    179178                                                              domain_dn, msg);
    180179
    181         workstation_list = samdb_result_string(msg, "userWorkstations", NULL);
     180        workstation_list = ldb_msg_find_attr_as_string(msg, "userWorkstations", NULL);
    182181
    183182        /* Quit if the account was disabled. */
    184183        if (acct_flags & ACB_DISABLED) {
    185                 DEBUG(1,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs));
     184                DEBUG(2,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs));
    186185                return NT_STATUS_ACCOUNT_DISABLED;
    187186        }
     
    189188        /* Quit if the account was locked out. */
    190189        if (acct_flags & ACB_AUTOLOCK) {
    191                 DEBUG(1,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs));
     190                DEBUG(2,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs));
    192191                return NT_STATUS_ACCOUNT_LOCKED_OUT;
    193192        }
     
    196195        unix_to_nt_time(&now, time(NULL));
    197196        if (now > acct_expiry) {
    198                 DEBUG(1,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));
     197                DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));
    199198                DEBUG(3,("authsam_account_ok: Account expired at '%s'.\n",
    200199                         nt_time_string(mem_ctx, acct_expiry)));
     
    204203        /* check for immediate expiry "must change at next logon" (but not if this is a password change request) */
    205204        if ((must_change_time == 0) && !password_change) {
    206                 DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n",
     205                DEBUG(2,("sam_account_ok: Account for user '%s' password must change!.\n",
    207206                         name_for_logs));
    208207                return NT_STATUS_PASSWORD_MUST_CHANGE;
     
    211210        /* check for expired password (but not if this is a password change request) */
    212211        if ((must_change_time < now) && !password_change) {
    213                 DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n",
     212                DEBUG(2,("sam_account_ok: Account for user '%s' password expired!.\n",
    214213                         name_for_logs));
    215                 DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
     214                DEBUG(2,("sam_account_ok: Password expired at '%s' unix time.\n",
    216215                         nt_time_string(mem_ctx, must_change_time)));
    217216                return NT_STATUS_PASSWORD_EXPIRED;
     
    269268}
    270269
    271 /* This function tests if a SID structure "sids" contains the SID "sid" */
    272 static bool sids_contains_sid(const struct dom_sid **sids, const int num_sids,
    273         const struct dom_sid *sid)
    274 {
    275         int i;
    276 
    277         for (i = 0; i < num_sids; i++) {
    278                 if (dom_sid_equal(sids[i], sid))
    279                         return true;
    280         }
    281         return false;
    282 }
    283 
    284 /*
    285  * This function generates the transitive closure of a given SID "sid" (it
    286  * basically expands nested groups of a SID).
    287  * If the SID isn't located in the "res_sids" structure yet and the
    288  * "only_childs" flag is negative, we add it to "res_sids".
    289  * Then we've always to consider the "memberOf" attributes. We invoke the
    290  * function recursively on each item of it with the "only_childs" flag set to
    291  * "false".
    292  * The "only_childs" flag is particularly useful if you have a user SID and
    293  * want to include all his groups (referenced with "memberOf") without his SID
    294  * itself.
    295  *
    296  * At the beginning "res_sids" should reference to a NULL pointer.
    297  */
    298 static NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx,
    299         const struct dom_sid *sid, const bool only_childs,
    300         TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids,
    301         int *num_res_sids)
    302 {
    303         const char * const attrs[] = { "memberOf", NULL };
    304         int i, ret;
    305         bool already_there;
    306         struct ldb_dn *tmp_dn;
    307         struct dom_sid *tmp_sid;
    308         TALLOC_CTX *tmp_ctx;
    309         struct ldb_message **res;
    310         NTSTATUS status;
    311 
    312         if (*res_sids == NULL) {
    313                 *num_res_sids = 0;
    314         }
    315 
    316         if (sid == NULL) {
    317                 return NT_STATUS_OK;
    318         }
    319 
    320         already_there = sids_contains_sid((const struct dom_sid**) *res_sids,
    321                 *num_res_sids, sid);
    322         if (already_there) {
    323                 return NT_STATUS_OK;
    324         }
    325 
    326         if (!only_childs) {
    327                 tmp_sid = dom_sid_dup(res_sids_ctx, sid);
    328                 NT_STATUS_HAVE_NO_MEMORY(tmp_sid);
    329                 *res_sids = talloc_realloc(res_sids_ctx, *res_sids,
    330                         struct dom_sid *, *num_res_sids + 1);
    331                 NT_STATUS_HAVE_NO_MEMORY(*res_sids);
    332                 (*res_sids)[*num_res_sids] = tmp_sid;
    333                 ++(*num_res_sids);
    334         }
    335 
    336         tmp_ctx = talloc_new(sam_ctx);
    337 
    338         ret = gendb_search(sam_ctx, tmp_ctx, NULL, &res, attrs,
    339                 "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid));
    340         if (ret != 1) {
    341                 talloc_free(tmp_ctx);
    342                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    343         }
    344 
    345         if (res[0]->num_elements == 0) {
    346                 talloc_free(res);
    347                 talloc_free(tmp_ctx);
    348                 return NT_STATUS_OK;
    349         }
    350 
    351         for (i = 0; i < res[0]->elements[0].num_values; i++) {
    352                 tmp_dn = ldb_dn_from_ldb_val(tmp_ctx, sam_ctx,
    353                         &res[0]->elements[0].values[i]);
    354                 tmp_sid = samdb_search_dom_sid(sam_ctx, tmp_ctx, tmp_dn,
    355                         "objectSid", NULL);
    356 
    357                 status = authsam_expand_nested_groups(sam_ctx, tmp_sid,
    358                         false, res_sids_ctx, res_sids, num_res_sids);
    359                 if (!NT_STATUS_IS_OK(status)) {
    360                         talloc_free(res);
    361                         talloc_free(tmp_ctx);
    362                         return status;
    363                 }
    364         }
    365 
    366         talloc_free(res);
    367         talloc_free(tmp_ctx);
    368 
    369         return NT_STATUS_OK;
    370 }
    371 
    372 _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx,
     270_PUBLIC_ NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx,
    373271                                           struct ldb_context *sam_ctx,
    374272                                           const char *netbios_name,
     
    378276                                           DATA_BLOB user_sess_key,
    379277                                           DATA_BLOB lm_sess_key,
    380                                            struct auth_serversupplied_info
    381                                                    **_server_info)
     278                                           struct auth_user_info_dc **_user_info_dc)
    382279{
    383280        NTSTATUS status;
    384         struct auth_serversupplied_info *server_info;
    385         const char *str;
    386         struct dom_sid *tmp_sid;
     281        struct auth_user_info_dc *user_info_dc;
     282        struct auth_user_info *info;
     283        const char *str, *filter;
    387284        /* SIDs for the account and his primary group */
    388285        struct dom_sid *account_sid;
    389         struct dom_sid *primary_group_sid;
     286        const char *primary_group_string;
     287        const char *primary_group_dn;
     288        DATA_BLOB primary_group_blob;
    390289        /* SID structures for the expanded group memberships */
    391         struct dom_sid **groupSIDs = NULL, **groupSIDs_2 = NULL;
    392         int num_groupSIDs = 0, num_groupSIDs_2 = 0, i;
    393         uint32_t userAccountControl;
    394 
    395         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    396         NT_STATUS_HAVE_NO_MEMORY(server_info);
    397 
    398         account_sid = samdb_result_dom_sid(server_info, msg, "objectSid");
    399         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, server_info);
    400 
    401         primary_group_sid = dom_sid_add_rid(server_info,
    402                 samdb_domain_sid(sam_ctx),
    403                 samdb_result_uint(msg, "primaryGroupID", ~0));
    404         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_sid, server_info);
    405 
    406         /* Expands the primary group */
    407         status = authsam_expand_nested_groups(sam_ctx, primary_group_sid, false,
    408                                               server_info, &groupSIDs, &num_groupSIDs);
     290        struct dom_sid *sids = NULL;
     291        unsigned int num_sids = 0, i;
     292        struct dom_sid *domain_sid;
     293        TALLOC_CTX *tmp_ctx;
     294        struct ldb_message_element *el;
     295
     296        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     297        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     298
     299        tmp_ctx = talloc_new(user_info_dc);
     300        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc);
     301
     302        sids = talloc_array(user_info_dc, struct dom_sid, 2);
     303        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc);
     304
     305        num_sids = 2;
     306
     307        account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid");
     308        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc);
     309
     310        status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL);
    409311        if (!NT_STATUS_IS_OK(status)) {
    410                 talloc_free(server_info);
     312                talloc_free(user_info_dc);
    411313                return status;
    412314        }
    413315
     316        sids[PRIMARY_USER_SID_INDEX] = *account_sid;
     317        sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
     318        sid_append_rid(&sids[PRIMARY_GROUP_SID_INDEX], ldb_msg_find_attr_as_uint(msg, "primaryGroupID", ~0));
     319
     320        /* Filter out builtin groups from this token.  We will search
     321         * for builtin groups later, and not include them in the PAC
     322         * on SamLogon validation info */
     323        filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED);
     324        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc);
     325
     326        primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]);
     327        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc);
     328
     329        primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string);
     330        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc);
     331
     332        primary_group_blob = data_blob_string_const(primary_group_dn);
     333
     334        /* Expands the primary group - this function takes in
     335         * memberOf-like values, so we fake one up with the
     336         * <SID=S-...> format of DN and then let it expand
     337         * them, as long as they meet the filter - so only
     338         * domain groups, not builtin groups
     339         *
     340         * The primary group is still treated specially, so we set the
     341         * 'only childs' flag to true
     342         */
     343        status = dsdb_expand_nested_groups(sam_ctx, &primary_group_blob, true, filter,
     344                                           user_info_dc, &sids, &num_sids);
     345        if (!NT_STATUS_IS_OK(status)) {
     346                talloc_free(user_info_dc);
     347                return status;
     348        }
     349
    414350        /* Expands the additional groups */
    415         status = authsam_expand_nested_groups(sam_ctx, account_sid, true,
    416                 server_info, &groupSIDs_2, &num_groupSIDs_2);
    417         if (!NT_STATUS_IS_OK(status)) {
    418                 talloc_free(server_info);
    419                 return status;
    420         }
    421 
    422         /* Merge the two expanded structures (groupSIDs, groupSIDs_2) */
    423         for (i = 0; i < num_groupSIDs_2; i++)
    424                 if (!sids_contains_sid((const struct dom_sid **) groupSIDs,
    425                                 num_groupSIDs, groupSIDs_2[i])) {
    426                         tmp_sid = dom_sid_dup(server_info, groupSIDs_2[i]);
    427                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp_sid, server_info);
    428                         groupSIDs = talloc_realloc(server_info, groupSIDs,
    429                                 struct dom_sid *, num_groupSIDs + 1);
    430                         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs,
    431                                 server_info);
    432                         groupSIDs[num_groupSIDs] = tmp_sid;
    433                         ++num_groupSIDs;
    434                 }
    435         talloc_free(groupSIDs_2);
    436 
    437         server_info->account_sid = account_sid;
    438         server_info->primary_group_sid = primary_group_sid;
    439        
    440         /* DCs also get SID_NT_ENTERPRISE_DCS */
    441         userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
    442         if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) {
    443                 groupSIDs = talloc_realloc(server_info, groupSIDs, struct dom_sid *,
    444                                            num_groupSIDs+1);
    445                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs, server_info);
    446                 groupSIDs[num_groupSIDs] = dom_sid_parse_talloc(groupSIDs, SID_NT_ENTERPRISE_DCS);
    447                 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs[num_groupSIDs], server_info);
    448                 num_groupSIDs++;
    449         }
    450 
    451         server_info->domain_groups = groupSIDs;
    452         server_info->n_domain_groups = num_groupSIDs;
    453 
    454         server_info->account_name = talloc_steal(server_info,
    455                 samdb_result_string(msg, "sAMAccountName", NULL));
    456 
    457         server_info->domain_name = talloc_strdup(server_info, domain_name);
    458         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->domain_name,
    459                 server_info);
    460 
    461         str = samdb_result_string(msg, "displayName", "");
    462         server_info->full_name = talloc_strdup(server_info, str);
    463         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->full_name, server_info);
    464 
    465         str = samdb_result_string(msg, "scriptPath", "");
    466         server_info->logon_script = talloc_strdup(server_info, str);
    467         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_script,
    468                 server_info);
    469 
    470         str = samdb_result_string(msg, "profilePath", "");
    471         server_info->profile_path = talloc_strdup(server_info, str);
    472         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->profile_path,
    473                 server_info);
    474 
    475         str = samdb_result_string(msg, "homeDirectory", "");
    476         server_info->home_directory = talloc_strdup(server_info, str);
    477         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_directory,
    478                 server_info);
    479 
    480         str = samdb_result_string(msg, "homeDrive", "");
    481         server_info->home_drive = talloc_strdup(server_info, str);
    482         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_drive, server_info);
    483 
    484         server_info->logon_server = talloc_strdup(server_info, netbios_name);
    485         NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_server,
    486                 server_info);
    487 
    488         server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
    489         server_info->last_logoff = samdb_result_last_logoff(msg);
    490         server_info->acct_expiry = samdb_result_account_expires(msg);
    491         server_info->last_password_change = samdb_result_nttime(msg,
     351        el = ldb_msg_find_element(msg, "memberOf");
     352        for (i = 0; el && i < el->num_values; i++) {
     353                /* This function takes in memberOf values and expands
     354                 * them, as long as they meet the filter - so only
     355                 * domain groups, not builtin groups */
     356                status = dsdb_expand_nested_groups(sam_ctx, &el->values[i], false, filter,
     357                                                   user_info_dc, &sids, &num_sids);
     358                if (!NT_STATUS_IS_OK(status)) {
     359                        talloc_free(user_info_dc);
     360                        return status;
     361                }
     362        }
     363
     364        user_info_dc->sids = sids;
     365        user_info_dc->num_sids = num_sids;
     366
     367        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     368        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     369
     370        info->account_name = talloc_steal(info,
     371                ldb_msg_find_attr_as_string(msg, "sAMAccountName", NULL));
     372
     373        info->domain_name = talloc_strdup(info, domain_name);
     374        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name,
     375                user_info_dc);
     376
     377        str = ldb_msg_find_attr_as_string(msg, "displayName", "");
     378        info->full_name = talloc_strdup(info, str);
     379        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc);
     380
     381        str = ldb_msg_find_attr_as_string(msg, "scriptPath", "");
     382        info->logon_script = talloc_strdup(info, str);
     383        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script,
     384                user_info_dc);
     385
     386        str = ldb_msg_find_attr_as_string(msg, "profilePath", "");
     387        info->profile_path = talloc_strdup(info, str);
     388        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path,
     389                user_info_dc);
     390
     391        str = ldb_msg_find_attr_as_string(msg, "homeDirectory", "");
     392        info->home_directory = talloc_strdup(info, str);
     393        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory,
     394                user_info_dc);
     395
     396        str = ldb_msg_find_attr_as_string(msg, "homeDrive", "");
     397        info->home_drive = talloc_strdup(info, str);
     398        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc);
     399
     400        info->logon_server = talloc_strdup(info, netbios_name);
     401        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server,
     402                user_info_dc);
     403
     404        info->last_logon = samdb_result_nttime(msg, "lastLogon", 0);
     405        info->last_logoff = samdb_result_last_logoff(msg);
     406        info->acct_expiry = samdb_result_account_expires(msg);
     407        info->last_password_change = samdb_result_nttime(msg,
    492408                "pwdLastSet", 0);
    493         server_info->allow_password_change
     409        info->allow_password_change
    494410                = samdb_result_allow_password_change(sam_ctx, mem_ctx,
    495411                        domain_dn, msg, "pwdLastSet");
    496         server_info->force_password_change
     412        info->force_password_change
    497413                = samdb_result_force_password_change(sam_ctx, mem_ctx,
    498414                        domain_dn, msg);
    499         server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);
    500         server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount",
     415        info->logon_count = ldb_msg_find_attr_as_uint(msg, "logonCount", 0);
     416        info->bad_password_count = ldb_msg_find_attr_as_uint(msg, "badPwdCount",
    501417                0);
    502418
    503         server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
     419        info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
    504420                                                          msg, domain_dn);
    505421
    506         server_info->user_session_key = data_blob_talloc_reference(server_info,
    507                 &user_sess_key);
    508         server_info->lm_session_key = data_blob_talloc_reference(server_info,
    509                 &lm_sess_key);
    510 
    511         server_info->authenticated = true;
    512 
    513         *_server_info = server_info;
     422        user_info_dc->user_session_key = data_blob_talloc(user_info_dc,
     423                                                         user_sess_key.data,
     424                                                         user_sess_key.length);
     425        if (user_sess_key.data) {
     426                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data,
     427                                                  user_info_dc);
     428        }
     429        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc,
     430                                                       lm_sess_key.data,
     431                                                       lm_sess_key.length);
     432        if (lm_sess_key.data) {
     433                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data,
     434                                                  user_info_dc);
     435        }
     436
     437        if (info->acct_flags & ACB_SVRTRUST) {
     438                /* the SID_NT_ENTERPRISE_DCS SID gets added into the
     439                   PAC */
     440                user_info_dc->sids = talloc_realloc(user_info_dc,
     441                                                   user_info_dc->sids,
     442                                                   struct dom_sid,
     443                                                   user_info_dc->num_sids+1);
     444                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     445                user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs;
     446                user_info_dc->num_sids++;
     447        }
     448
     449        if ((info->acct_flags & (ACB_PARTIAL_SECRETS_ACCOUNT | ACB_WSTRUST)) ==
     450            (ACB_PARTIAL_SECRETS_ACCOUNT | ACB_WSTRUST)) {
     451                /* the DOMAIN_RID_ENTERPRISE_READONLY_DCS PAC */
     452                user_info_dc->sids = talloc_realloc(user_info_dc,
     453                                                   user_info_dc->sids,
     454                                                   struct dom_sid,
     455                                                   user_info_dc->num_sids+1);
     456                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc);
     457                user_info_dc->sids[user_info_dc->num_sids] = *domain_sid;
     458                sid_append_rid(&user_info_dc->sids[user_info_dc->num_sids],
     459                            DOMAIN_RID_ENTERPRISE_READONLY_DCS);
     460                user_info_dc->num_sids++;
     461        }
     462
     463        info->authenticated = true;
     464
     465        talloc_free(tmp_ctx);
     466        *_user_info_dc = user_info_dc;
    514467
    515468        return NT_STATUS_OK;
     
    539492       
    540493        /* pull the user attributes */
    541         ret = gendb_search_single_extended_dn(sam_ctx, tmp_ctx, user_dn,
    542                 LDB_SCOPE_BASE, msg, attrs, "(objectClass=*)");
     494        ret = dsdb_search_one(sam_ctx, tmp_ctx, msg, user_dn,
     495                              LDB_SCOPE_BASE, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
    543496        if (ret != LDB_SUCCESS) {
    544497                talloc_free(tmp_ctx);
     
    551504        return NT_STATUS_OK;
    552505}
     506
     507/* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available, and for tokenGroups in the DSDB stack.
     508
     509 Supply either a principal or a DN
     510*/
     511NTSTATUS authsam_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
     512                                           struct loadparm_context *lp_ctx,
     513                                           struct ldb_context *sam_ctx,
     514                                           const char *principal,
     515                                           struct ldb_dn *user_dn,
     516                                           struct auth_user_info_dc **user_info_dc)
     517{
     518        NTSTATUS nt_status;
     519        DATA_BLOB user_sess_key = data_blob(NULL, 0);
     520        DATA_BLOB lm_sess_key = data_blob(NULL, 0);
     521
     522        struct ldb_message *msg;
     523        struct ldb_dn *domain_dn;
     524
     525        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     526        if (!tmp_ctx) {
     527                return NT_STATUS_NO_MEMORY;
     528        }
     529
     530        if (principal) {
     531                nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
     532                                                      user_attrs, &domain_dn, &msg);
     533                if (!NT_STATUS_IS_OK(nt_status)) {
     534                        talloc_free(tmp_ctx);
     535                        return nt_status;
     536                }
     537        } else if (user_dn) {
     538                struct dom_sid *user_sid, *domain_sid;
     539                int ret;
     540                /* pull the user attributes */
     541                ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn,
     542                                      LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     543                if (ret == LDB_ERR_NO_SUCH_OBJECT) {
     544                        talloc_free(tmp_ctx);
     545                        return NT_STATUS_NO_SUCH_USER;
     546                } else if (ret != LDB_SUCCESS) {
     547                        talloc_free(tmp_ctx);
     548                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     549                }
     550
     551                user_sid = samdb_result_dom_sid(msg, msg, "objectSid");
     552
     553                nt_status = dom_sid_split_rid(tmp_ctx, user_sid, &domain_sid, NULL);
     554                if (!NT_STATUS_IS_OK(nt_status)) {
     555                        return nt_status;
     556                }
     557
     558                domain_dn = samdb_search_dn(sam_ctx, mem_ctx, NULL,
     559                                          "(&(objectSid=%s)(objectClass=domain))",
     560                                            ldap_encode_ndr_dom_sid(tmp_ctx, domain_sid));
     561                if (!domain_dn) {
     562                        DEBUG(3, ("authsam_get_user_info_dc_principal: Failed to find domain with: SID %s\n",
     563                                  dom_sid_string(tmp_ctx, domain_sid)));
     564                        return NT_STATUS_NO_SUCH_USER;
     565                }
     566
     567        } else {
     568                return NT_STATUS_INVALID_PARAMETER;
     569        }
     570
     571        nt_status = authsam_make_user_info_dc(tmp_ctx, sam_ctx,
     572                                             lpcfg_netbios_name(lp_ctx),
     573                                             lpcfg_workgroup(lp_ctx),
     574                                             domain_dn,
     575                                             msg,
     576                                             user_sess_key, lm_sess_key,
     577                                             user_info_dc);
     578        if (!NT_STATUS_IS_OK(nt_status)) {
     579                talloc_free(tmp_ctx);
     580                return nt_status;
     581        }
     582
     583        talloc_steal(mem_ctx, *user_info_dc);
     584        talloc_free(tmp_ctx);
     585
     586        return NT_STATUS_OK;
     587}
  • vendor/current/source4/auth/samba_server_gensec.c

    r414 r740  
    3939        struct gensec_security *gensec_ctx;
    4040        struct auth_context *auth_context;
     41
     42        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     43        if (!tmp_ctx) {
     44                return NT_STATUS_NO_MEMORY;
     45        }
    4146       
    42         nt_status = auth_context_create(mem_ctx,
     47        nt_status = auth_context_create(tmp_ctx,
    4348                                        event_ctx,
    4449                                        msg_ctx,
     
    4853        if (!NT_STATUS_IS_OK(nt_status)) {
    4954                DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(nt_status)));
     55                talloc_free(tmp_ctx);
    5056                return nt_status;
    5157        }
    5258
    53         nt_status = gensec_server_start(mem_ctx,
     59        nt_status = gensec_server_start(tmp_ctx,
    5460                                        event_ctx,
    55                                         lp_gensec_settings(mem_ctx, lp_ctx),
     61                                        lpcfg_gensec_settings(mem_ctx, lp_ctx),
    5662                                        auth_context,
    5763                                        &gensec_ctx);
    5864        if (!NT_STATUS_IS_OK(nt_status)) {
    59                 talloc_free(auth_context);
     65                talloc_free(tmp_ctx);
    6066                DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(nt_status)));
    6167                return nt_status;
     
    6773                gensec_set_target_service(gensec_ctx, target_service);
    6874        }
    69         *gensec_context = gensec_ctx;
     75        *gensec_context = talloc_steal(mem_ctx, gensec_ctx);
     76        talloc_free(tmp_ctx);
    7077        return nt_status;
    7178}
  • vendor/current/source4/auth/session.c

    r414 r740  
    33   Authentication utility functions
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    Copyright (C) Andrew Bartlett 2001
     5   Copyright (C) Andrew Bartlett 2001-2010
    66   Copyright (C) Jeremy Allison 2000-2001
    77   Copyright (C) Rafal Szczesniak 2002
     
    2424#include "includes.h"
    2525#include "auth/auth.h"
     26#include "auth/auth_sam.h"
     27#include "auth/credentials/credentials.h"
     28#include "auth/credentials/credentials_krb5.h"
    2629#include "libcli/security/security.h"
    2730#include "libcli/auth/libcli_auth.h"
    2831#include "dsdb/samdb/samdb.h"
    29 #include "auth/credentials/credentials.h"
    30 #include "param/param.h"
    3132#include "auth/session_proto.h"
     33#include "system/kerberos.h"
     34#include <gssapi/gssapi.h>
    3235
    3336_PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
    34                                             struct tevent_context *event_ctx,
    35                                             struct loadparm_context *lp_ctx)
     37                                            struct loadparm_context *lp_ctx)
    3638{
    3739        NTSTATUS nt_status;
    3840        struct auth_session_info *session_info = NULL;
    39         nt_status = auth_anonymous_session_info(mem_ctx, event_ctx, lp_ctx, &session_info);
     41        nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info);
    4042        if (!NT_STATUS_IS_OK(nt_status)) {
    4143                return NULL;
     
    4446}
    4547
    46 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
    47                                      struct tevent_context *event_ctx,
    48                                      struct loadparm_context *lp_ctx,
    49                                      struct auth_session_info **_session_info)
    50 {
    51         NTSTATUS nt_status;
    52         struct auth_serversupplied_info *server_info = NULL;
    53         struct auth_session_info *session_info = NULL;
    54         TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    55        
    56         nt_status = auth_anonymous_server_info(mem_ctx,
    57                                                lp_netbios_name(lp_ctx),
    58                                                &server_info);
    59         if (!NT_STATUS_IS_OK(nt_status)) {
    60                 talloc_free(mem_ctx);
    61                 return nt_status;
    62         }
    63 
    64         /* references the server_info into the session_info */
    65         nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info);
    66         talloc_free(mem_ctx);
    67 
    68         NT_STATUS_NOT_OK_RETURN(nt_status);
    69 
    70         session_info->credentials = cli_credentials_init(session_info);
    71         if (!session_info->credentials) {
    72                 return NT_STATUS_NO_MEMORY;
    73         }
    74 
    75         cli_credentials_set_conf(session_info->credentials, lp_ctx);
    76         cli_credentials_set_anonymous(session_info->credentials);
    77        
    78         *_session_info = session_info;
    79 
    80         return NT_STATUS_OK;
    81 }
    82 
    83 _PUBLIC_ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
    84                                     const char *netbios_name,
    85                                     struct auth_serversupplied_info **_server_info)
    86 {
    87         struct auth_serversupplied_info *server_info;
    88         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    89         NT_STATUS_HAVE_NO_MEMORY(server_info);
    90 
    91         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    92         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    93 
    94         /* is this correct? */
    95         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    96         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    97 
    98         server_info->n_domain_groups = 0;
    99         server_info->domain_groups = NULL;
    100 
    101         /* annoying, but the Anonymous really does have a session key... */
    102         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    103         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    104 
    105         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    106         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    107 
    108         /*  and it is all zeros! */
    109         data_blob_clear(&server_info->user_session_key);
    110         data_blob_clear(&server_info->lm_session_key);
    111 
    112         server_info->account_name = talloc_strdup(server_info, "ANONYMOUS LOGON");
    113         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    114 
    115         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
    116         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    117 
    118         server_info->full_name = talloc_strdup(server_info, "Anonymous Logon");
    119         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    120 
    121         server_info->logon_script = talloc_strdup(server_info, "");
    122         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    123 
    124         server_info->profile_path = talloc_strdup(server_info, "");
    125         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    126 
    127         server_info->home_directory = talloc_strdup(server_info, "");
    128         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    129 
    130         server_info->home_drive = talloc_strdup(server_info, "");
    131         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    132 
    133         server_info->logon_server = talloc_strdup(server_info, netbios_name);
    134         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
    135 
    136         server_info->last_logon = 0;
    137         server_info->last_logoff = 0;
    138         server_info->acct_expiry = 0;
    139         server_info->last_password_change = 0;
    140         server_info->allow_password_change = 0;
    141         server_info->force_password_change = 0;
    142 
    143         server_info->logon_count = 0;
    144         server_info->bad_password_count = 0;
    145 
    146         server_info->acct_flags = ACB_NORMAL;
    147 
    148         server_info->authenticated = false;
    149 
    150         *_server_info = server_info;
    151 
    152         return NT_STATUS_OK;
    153 }
    154 
    155 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
    156                                     struct tevent_context *event_ctx,
    157                                     struct loadparm_context *lp_ctx,
    158                                     struct auth_serversupplied_info *server_info,
    159                                     struct auth_session_info **_session_info)
     48_PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
     49                                             struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */
     50                                             struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
     51                                             struct auth_user_info_dc *user_info_dc,
     52                                             uint32_t session_info_flags,
     53                                             struct auth_session_info **_session_info)
    16054{
    16155        struct auth_session_info *session_info;
    16256        NTSTATUS nt_status;
    163 
    164         session_info = talloc(mem_ctx, struct auth_session_info);
    165         NT_STATUS_HAVE_NO_MEMORY(session_info);
    166 
    167         session_info->server_info = talloc_reference(session_info, server_info);
     57        unsigned int i, num_sids = 0;
     58
     59        const char *filter;
     60
     61        struct dom_sid *sids = NULL;
     62        const struct dom_sid *anonymous_sid, *system_sid;
     63
     64        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     65        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     66
     67        session_info = talloc(tmp_ctx, struct auth_session_info);
     68        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx);
     69
     70        session_info->info = talloc_reference(session_info, user_info_dc->info);
     71
     72        session_info->torture = talloc_zero(session_info, struct auth_user_info_torture);
     73        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx);
     74        session_info->torture->num_dc_sids = user_info_dc->num_sids;
     75        session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids);
     76        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx);
    16877
    16978        /* unless set otherwise, the session key is the user session
    17079         * key from the auth subsystem */
    171         session_info->session_key = server_info->user_session_key;
     80        session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length);
     81        if (!session_info->session_key.data && session_info->session_key.length) {
     82                NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx);
     83        }
     84
     85        anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS);
     86        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx);
     87
     88        system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM);
     89        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx);
     90
     91        sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids);
     92        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx);
     93        if (!sids) {
     94                talloc_free(tmp_ctx);
     95                return NT_STATUS_NO_MEMORY;
     96        }
     97
     98        num_sids = user_info_dc->num_sids;
     99
     100        for (i=0; i < user_info_dc->num_sids; i++) {
     101                sids[i] = user_info_dc->sids[i];
     102        }
     103
     104        if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     105                /* Don't expand nested groups of system, anonymous etc*/
     106        } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) {
     107                /* Don't expand nested groups of system, anonymous etc*/
     108        } else if (sam_ctx) {
     109                filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
     110                                         GROUP_TYPE_BUILTIN_LOCAL_GROUP);
     111
     112                /* Search for each group in the token */
     113                for (i = 0; i < user_info_dc->num_sids; i++) {
     114                        char *sid_string;
     115                        const char *sid_dn;
     116                        DATA_BLOB sid_blob;
     117                       
     118                        sid_string = dom_sid_string(tmp_ctx,
     119                                                      &user_info_dc->sids[i]);
     120                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc);
     121                       
     122                        sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
     123                        talloc_free(sid_string);
     124                        NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc);
     125                        sid_blob = data_blob_string_const(sid_dn);
     126                       
     127                        /* This function takes in memberOf values and expands
     128                         * them, as long as they meet the filter - so only
     129                         * builtin groups
     130                         *
     131                         * We already have the SID in the token, so set
     132                         * 'only childs' flag to true */
     133                        nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter,
     134                                                              tmp_ctx, &sids, &num_sids);
     135                        if (!NT_STATUS_IS_OK(nt_status)) {
     136                                talloc_free(tmp_ctx);
     137                                return nt_status;
     138                        }
     139                }
     140        }
    172141
    173142        nt_status = security_token_create(session_info,
    174                                           event_ctx,
    175143                                          lp_ctx,
    176                                           server_info->account_sid,
    177                                           server_info->primary_group_sid,
    178                                           server_info->n_domain_groups,
    179                                           server_info->domain_groups,
    180                                           server_info->authenticated,
     144                                          num_sids,
     145                                          sids,
     146                                          session_info_flags,
    181147                                          &session_info->security_token);
    182         NT_STATUS_NOT_OK_RETURN(nt_status);
     148        NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx);
    183149
    184150        session_info->credentials = NULL;
    185151
     152        talloc_steal(mem_ctx, session_info);
    186153        *_session_info = session_info;
     154        talloc_free(tmp_ctx);
    187155        return NT_STATUS_OK;
     156}
     157
     158/* Create a session_info structure from the
     159 * auth_session_info_transport we were forwarded over named pipe
     160 * forwarding.
     161 *
     162 * NOTE: The stucture members of session_info_transport are stolen
     163 * with talloc_move() into auth_session_info for long term use
     164 */
     165struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
     166                                                           struct auth_session_info_transport *session_info_transport,
     167                                                           struct loadparm_context *lp_ctx,
     168                                                           const char **reason)
     169{
     170        struct auth_session_info *session_info;
     171        session_info = talloc_zero(mem_ctx, struct auth_session_info);
     172        if (!session_info) {
     173                *reason = "failed to allocate session_info";
     174                return NULL;
     175        }
     176
     177        session_info->security_token = talloc_move(session_info, &session_info_transport->security_token);
     178        session_info->info = talloc_move(session_info, &session_info_transport->info);
     179        session_info->session_key = session_info_transport->session_key;
     180        session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data);
     181
     182        if (session_info_transport->exported_gssapi_credentials.length) {
     183                struct cli_credentials *creds;
     184                OM_uint32 minor_status;
     185                gss_buffer_desc cred_token;
     186                gss_cred_id_t cred_handle;
     187                const char *error_string;
     188                int ret;
     189
     190                DEBUG(10, ("Delegated credentials supplied by client\n"));
     191
     192                cred_token.value = session_info_transport->exported_gssapi_credentials.data;
     193                cred_token.length = session_info_transport->exported_gssapi_credentials.length;
     194
     195                ret = gss_import_cred(&minor_status,
     196                                      &cred_token,
     197                                      &cred_handle);
     198                if (ret != GSS_S_COMPLETE) {
     199                        *reason = "Internal error in gss_import_cred()";
     200                        return NULL;
     201                }
     202
     203                creds = cli_credentials_init(session_info);
     204                if (!creds) {
     205                        *reason = "Out of memory in cli_credentials_init()";
     206                        return NULL;
     207                }
     208                session_info->credentials = creds;
     209
     210                cli_credentials_set_conf(creds, lp_ctx);
     211                /* Just so we don't segfault trying to get at a username */
     212                cli_credentials_set_anonymous(creds);
     213
     214                ret = cli_credentials_set_client_gss_creds(creds,
     215                                                           lp_ctx,
     216                                                           cred_handle,
     217                                                           CRED_SPECIFIED,
     218                                                           &error_string);
     219                if (ret) {
     220                        *reason = talloc_asprintf(mem_ctx,
     221                                                  "Failed to set pipe forwarded"
     222                                                  "creds: %s\n", error_string);
     223                        return NULL;
     224                }
     225
     226                /* This credential handle isn't useful for password
     227                 * authentication, so ensure nobody tries to do that */
     228                cli_credentials_set_kerberos_state(creds,
     229                                                   CRED_MUST_USE_KERBEROS);
     230
     231        }
     232
     233        return session_info;
     234}
     235
     236
     237/* Create a auth_session_info_transport from an auth_session_info.
     238 *
     239 * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned.  They are only valid for the lifetime of the struct auth_session_info
     240 *
     241 * This isn't normally an issue, as the auth_session_info has a very long typical life
     242 */
     243NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
     244                                                  struct auth_session_info *session_info,
     245                                                  struct tevent_context *event_ctx,
     246                                                  struct loadparm_context *lp_ctx,
     247                                                  struct auth_session_info_transport **transport_out)
     248{
     249
     250        struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport);
     251        session_info_transport->security_token = talloc_reference(session_info, session_info->security_token);
     252        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token);
     253
     254        session_info_transport->info = talloc_reference(session_info, session_info->info);
     255        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info);
     256
     257        session_info_transport->session_key = session_info->session_key;
     258        session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data);
     259        if (!session_info_transport->session_key.data && session_info->session_key.length) {
     260                return NT_STATUS_NO_MEMORY;
     261        }
     262
     263        if (session_info->credentials) {
     264                struct gssapi_creds_container *gcc;
     265                OM_uint32 gret;
     266                OM_uint32 minor_status;
     267                gss_buffer_desc cred_token;
     268                const char *error_string;
     269                int ret;
     270
     271                ret = cli_credentials_get_client_gss_creds(session_info->credentials,
     272                                                           event_ctx,
     273                                                           lp_ctx,
     274                                                           &gcc, &error_string);
     275                if (ret != 0) {
     276                        *transport_out = session_info_transport;
     277                        return NT_STATUS_OK;
     278                }
     279
     280                gret = gss_export_cred(&minor_status,
     281                                       gcc->creds,
     282                                       &cred_token);
     283                if (gret != GSS_S_COMPLETE) {
     284                        return NT_STATUS_INTERNAL_ERROR;
     285                }
     286
     287                if (cred_token.length) {
     288                        session_info_transport->exported_gssapi_credentials
     289                                = data_blob_talloc(session_info_transport,
     290                                                   cred_token.value,
     291                                                   cred_token.length);
     292                        gss_release_buffer(&minor_status, &cred_token);
     293                        NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data);
     294                }
     295        }
     296        *transport_out = session_info_transport;
     297        return NT_STATUS_OK;
     298}
     299
     300
     301/* Produce a session_info for an arbitary DN or principal in the local
     302 * DB, assuming the local DB holds all the groups
     303 *
     304 * Supply either a principal or a DN
     305 */
     306NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
     307                                            struct loadparm_context *lp_ctx,
     308                                            struct ldb_context *sam_ctx,
     309                                            const char *principal,
     310                                            struct ldb_dn *user_dn,
     311                                            uint32_t session_info_flags,
     312                                            struct auth_session_info **session_info)
     313{
     314        NTSTATUS nt_status;
     315        struct auth_user_info_dc *user_info_dc;
     316        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     317        if (!tmp_ctx) {
     318                return NT_STATUS_NO_MEMORY;
     319        }
     320        nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx,
     321                                                      principal, user_dn,
     322                                                      &user_info_dc);
     323        if (!NT_STATUS_IS_OK(nt_status)) {
     324                talloc_free(tmp_ctx);
     325                return nt_status;
     326        }
     327
     328        nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx,
     329                                               user_info_dc, session_info_flags,
     330                                               session_info);
     331
     332        if (NT_STATUS_IS_OK(nt_status)) {
     333                talloc_steal(mem_ctx, *session_info);
     334        }
     335        talloc_free(tmp_ctx);
     336        return nt_status;
    188337}
    189338
     
    199348        }
    200349
    201         security_token_debug(dbg_lev, session_info->security_token);
    202 }
    203 
     350        security_token_debug(0, dbg_lev, session_info->security_token);
     351}
     352
  • vendor/current/source4/auth/session.h

    r414 r740  
    2222#define _SAMBA_AUTH_SESSION_H
    2323
    24 struct auth_session_info {
    25         struct security_token *security_token;
    26         struct auth_serversupplied_info *server_info;
    27         DATA_BLOB session_key;
    28         struct cli_credentials *credentials;
    29 };
    30 
     24#include "librpc/gen_ndr/security.h"
    3125#include "librpc/gen_ndr/netlogon.h"
     26#include "librpc/gen_ndr/auth.h"
    3227
    3328struct tevent_context;
    34 
     29struct ldb_context;
     30struct ldb_dn;
    3531/* Create a security token for a session SYSTEM (the most
    3632 * trusted/prvilaged account), including the local machine account as
    3733 * the off-host credentials */
    38 struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) ;
     34struct auth_session_info *system_session(struct loadparm_context *lp_ctx) ;
    3935
    40 /*
    41  * Create a system session, but with anonymous credentials (so we do
    42  * not need to open secrets.ldb)
     36NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx,
     37                                             const char *netbios_name,
     38                                             struct auth_user_info_dc **interim_info);
     39NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
     40                                    struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */
     41                                    struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */
     42                                    struct auth_user_info_dc *interim_info,
     43                                    uint32_t session_info_flags,
     44                                    struct auth_session_info **session_info);
     45NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
     46                                     struct loadparm_context *lp_ctx,
     47                                     struct auth_session_info **session_info);
     48struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
     49                                                           struct auth_session_info_transport *session_info_transport,
     50                                                           struct loadparm_context *lp_ctx,
     51                                                           const char **reason);
     52NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx,
     53                                                  struct auth_session_info *session_info,
     54                                                  struct tevent_context *event_ctx,
     55                                                  struct loadparm_context *lp_ctx,
     56                                                  struct auth_session_info_transport **transport_out);
     57
     58/* Produce a session_info for an arbitary DN or principal in the local
     59 * DB, assuming the local DB holds all the groups
     60 *
     61 * Supply either a principal or a DN
    4362 */
    44 struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx);
    45 
    46 
    47 NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx,
    48                                     const char *netbios_name,
    49                                     struct auth_serversupplied_info **_server_info) ;
    50 NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx,
    51                                     struct tevent_context *event_ctx,
    52                                     struct loadparm_context *lp_ctx,
    53                                     struct auth_serversupplied_info *server_info,
    54                                     struct auth_session_info **_session_info) ;
    55 
    56 NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
    57                                      struct tevent_context *ev_ctx,
    58                                      struct loadparm_context *lp_ctx,
    59                                      struct auth_session_info **_session_info);
     63NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx,
     64                                            struct loadparm_context *lp_ctx,
     65                                            struct ldb_context *sam_ctx,
     66                                            const char *principal,
     67                                            struct ldb_dn *user_dn,
     68                                            uint32_t session_info_flags,
     69                                            struct auth_session_info **session_info);
    6070
    6171struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx,
    62                                             struct tevent_context *event_ctx,
    6372                                            struct loadparm_context *lp_ctx);
    6473
  • vendor/current/source4/auth/system_session.c

    r414 r740  
    33   Authentication utility functions
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    Copyright (C) Andrew Bartlett 2001
     5   Copyright (C) Andrew Bartlett 2001-2010
    66   Copyright (C) Jeremy Allison 2000-2001
    77   Copyright (C) Rafal Szczesniak 2002
     
    2424#include "includes.h"
    2525#include "libcli/security/security.h"
    26 #include "libcli/auth/libcli_auth.h"
    2726#include "auth/credentials/credentials.h"
    2827#include "param/param.h"
    29 #include "auth/auth.h" /* for auth_serversupplied_info */
     28#include "auth/auth.h" /* for auth_user_info_dc */
    3029#include "auth/session.h"
    3130#include "auth/system_session_proto.h"
    3231
    33 /**
    34  * Create the SID list for this user.
    35  *
    36  * @note Specialised version for system sessions that doesn't use the SAM.
     32
     33/*
     34  prevent the static system session being freed
    3735 */
    38 static NTSTATUS create_token(TALLOC_CTX *mem_ctx,
    39                                struct dom_sid *user_sid,
    40                                struct dom_sid *group_sid,
    41                                int n_groupSIDs,
    42                                struct dom_sid **groupSIDs,
    43                                bool is_authenticated,
    44                                struct security_token **token)
    45 {
    46         struct security_token *ptoken;
    47         int i;
    48 
    49         ptoken = security_token_initialise(mem_ctx);
    50         NT_STATUS_HAVE_NO_MEMORY(ptoken);
    51 
    52         ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5);
    53         NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
    54 
    55         ptoken->user_sid = talloc_reference(ptoken, user_sid);
    56         ptoken->group_sid = talloc_reference(ptoken, group_sid);
    57         ptoken->privilege_mask = 0;
    58 
    59         ptoken->sids[0] = ptoken->user_sid;
    60         ptoken->sids[1] = ptoken->group_sid;
    61 
    62         /*
    63          * Finally add the "standard" SIDs.
    64          * The only difference between guest and "anonymous"
    65          * is the addition of Authenticated_Users.
    66          */
    67         ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD);
    68         NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]);
    69         ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK);
    70         NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]);
    71         ptoken->num_sids = 4;
    72 
    73         if (is_authenticated) {
    74                 ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS);
    75                 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]);
    76                 ptoken->num_sids++;
    77         }
    78 
    79         for (i = 0; i < n_groupSIDs; i++) {
    80                 size_t check_sid_idx;
    81                 for (check_sid_idx = 1;
    82                      check_sid_idx < ptoken->num_sids;
    83                      check_sid_idx++) {
    84                         if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) {
    85                                 break;
    86                         }
    87                 }
    88 
    89                 if (check_sid_idx == ptoken->num_sids) {
    90                         ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]);
    91                 }
    92         }
    93 
    94         *token = ptoken;
    95 
    96         /* Shortcuts to prevent recursion and avoid lookups */
    97         if (ptoken->user_sid == NULL) {
    98                 ptoken->privilege_mask = 0;
    99                 return NT_STATUS_OK;
    100         }
    101        
    102         if (security_token_is_system(ptoken)) {
    103                 ptoken->privilege_mask = ~0;
    104                 return NT_STATUS_OK;
    105         }
    106        
    107         if (security_token_is_anonymous(ptoken)) {
    108                 ptoken->privilege_mask = 0;
    109                 return NT_STATUS_OK;
    110         }
    111 
    112         DEBUG(0, ("Created token was not system or anonymous token!"));
    113         *token = NULL;
    114         return NT_STATUS_INTERNAL_ERROR;
    115 }
    116 
    117 static NTSTATUS generate_session_info(TALLOC_CTX *mem_ctx,
    118                                     struct auth_serversupplied_info *server_info,
    119                                     struct auth_session_info **_session_info)
    120 {
    121         struct auth_session_info *session_info;
    122         NTSTATUS nt_status;
    123 
    124         session_info = talloc(mem_ctx, struct auth_session_info);
    125         NT_STATUS_HAVE_NO_MEMORY(session_info);
    126 
    127         session_info->server_info = talloc_reference(session_info, server_info);
    128 
    129         /* unless set otherwise, the session key is the user session
    130          * key from the auth subsystem */
    131         session_info->session_key = server_info->user_session_key;
    132 
    133         nt_status = create_token(session_info,
    134                                           server_info->account_sid,
    135                                           server_info->primary_group_sid,
    136                                           server_info->n_domain_groups,
    137                                           server_info->domain_groups,
    138                                           server_info->authenticated,
    139                                           &session_info->security_token);
    140         NT_STATUS_NOT_OK_RETURN(nt_status);
    141 
    142         session_info->credentials = NULL;
    143 
    144         *_session_info = session_info;
    145         return NT_STATUS_OK;
    146 }
    147 
    148 
     36static int system_session_destructor(struct auth_session_info *info)
     37{
     38        return -1;
     39}
    14940
    15041/* Create a security token for a session SYSTEM (the most
     
    15243 * the off-host credentials
    15344 */
    154 _PUBLIC_ struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    155 {
     45_PUBLIC_ struct auth_session_info *system_session(struct loadparm_context *lp_ctx)
     46{
     47        static struct auth_session_info *static_session;
    15648        NTSTATUS nt_status;
    157         struct auth_session_info *session_info = NULL;
    158         nt_status = auth_system_session_info(mem_ctx,
     49
     50        if (static_session) {
     51                return static_session;
     52        }
     53
     54        nt_status = auth_system_session_info(talloc_autofree_context(),
    15955                                             lp_ctx,
    160                                              &session_info);
     56                                             &static_session);
    16157        if (!NT_STATUS_IS_OK(nt_status)) {
     58                talloc_free(static_session);
     59                static_session = NULL;
    16260                return NULL;
    16361        }
    164         return session_info;
    165 }
    166 
    167 static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx,
    168                                           struct loadparm_context *lp_ctx,
    169                                           bool anonymous_credentials,
    170                                           struct auth_session_info **_session_info)
     62        talloc_set_destructor(static_session, system_session_destructor);
     63        return static_session;
     64}
     65
     66NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx,
     67                                  struct loadparm_context *lp_ctx,
     68                                  struct auth_session_info **_session_info)
    17169{
    17270        NTSTATUS nt_status;
    173         struct auth_serversupplied_info *server_info = NULL;
     71        struct auth_user_info_dc *user_info_dc = NULL;
    17472        struct auth_session_info *session_info = NULL;
    17573        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    17674       
    177         nt_status = auth_system_server_info(mem_ctx, lp_netbios_name(lp_ctx),
    178                                             &server_info);
     75        nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
     76                                            &user_info_dc);
    17977        if (!NT_STATUS_IS_OK(nt_status)) {
    18078                talloc_free(mem_ctx);
     
    18280        }
    18381
    184         /* references the server_info into the session_info */
    185         nt_status = generate_session_info(parent_ctx, server_info, &session_info);
     82        /* references the user_info_dc into the session_info */
     83        nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
    18684        talloc_free(mem_ctx);
    18785
     
    19593        cli_credentials_set_conf(session_info->credentials, lp_ctx);
    19694
    197         if (anonymous_credentials) {
    198                 cli_credentials_set_anonymous(session_info->credentials);
    199         } else {
    200                 cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
    201         }
     95        cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx);
    20296        *_session_info = session_info;
    20397
     
    20599}
    206100
    207 /*
    208   Create a system session, but with anonymous credentials (so we do not need to open secrets.ldb)
    209 */
    210 _PUBLIC_ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
    211 {
    212         NTSTATUS nt_status;
    213         struct auth_session_info *session_info = NULL;
    214         nt_status = _auth_system_session_info(mem_ctx, lp_ctx, false, &session_info);
    215         if (!NT_STATUS_IS_OK(nt_status)) {
    216                 return NULL;
    217         }
    218         return session_info;
    219 }
    220 
    221 
    222 
    223 _PUBLIC_ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx,
    224                                            struct loadparm_context *lp_ctx,
    225                                            struct auth_session_info **_session_info)
    226 {
    227         return _auth_system_session_info(parent_ctx,
    228                         lp_ctx,
    229                         lp_parm_bool(lp_ctx, NULL, "system", "anonymous", false),
    230                         _session_info);
    231 }
    232 
    233 NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name,
    234                                  struct auth_serversupplied_info **_server_info)
    235 {
    236         struct auth_serversupplied_info *server_info;
    237 
    238         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    239         NT_STATUS_HAVE_NO_MEMORY(server_info);
    240 
    241         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_SYSTEM);
    242         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    243 
    244         /* is this correct? */
    245         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS);
    246         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    247 
    248         server_info->n_domain_groups = 0;
    249         server_info->domain_groups = NULL;
     101NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name,
     102                                 struct auth_user_info_dc **_user_info_dc)
     103{
     104        struct auth_user_info_dc *user_info_dc;
     105        struct auth_user_info *info;
     106
     107        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     108        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     109
     110        /* This returns a pointer to a struct dom_sid, which is the
     111         * same as a 1 element list of struct dom_sid */
     112        user_info_dc->num_sids = 1;
     113        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_SYSTEM);
     114        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
    250115
    251116        /* annoying, but the Anonymous really does have a session key,
    252117           and it is all zeros! */
    253         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    254         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    255 
    256         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    257         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    258 
    259         data_blob_clear(&server_info->user_session_key);
    260         data_blob_clear(&server_info->lm_session_key);
    261 
    262         server_info->account_name = talloc_strdup(server_info, "SYSTEM");
    263         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    264 
    265         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
    266         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    267 
    268         server_info->full_name = talloc_strdup(server_info, "System");
    269         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    270 
    271         server_info->logon_script = talloc_strdup(server_info, "");
    272         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    273 
    274         server_info->profile_path = talloc_strdup(server_info, "");
    275         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    276 
    277         server_info->home_directory = talloc_strdup(server_info, "");
    278         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    279 
    280         server_info->home_drive = talloc_strdup(server_info, "");
    281         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    282 
    283         server_info->logon_server = talloc_strdup(server_info, netbios_name);
    284         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
    285 
    286         server_info->last_logon = 0;
    287         server_info->last_logoff = 0;
    288         server_info->acct_expiry = 0;
    289         server_info->last_password_change = 0;
    290         server_info->allow_password_change = 0;
    291         server_info->force_password_change = 0;
    292 
    293         server_info->logon_count = 0;
    294         server_info->bad_password_count = 0;
    295 
    296         server_info->acct_flags = ACB_NORMAL;
    297 
    298         server_info->authenticated = true;
    299 
    300         *_server_info = server_info;
     118        user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     119        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
     120
     121        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     122        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
     123
     124        data_blob_clear(&user_info_dc->user_session_key);
     125        data_blob_clear(&user_info_dc->lm_session_key);
     126
     127        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     128        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     129
     130        info->account_name = talloc_strdup(info, "SYSTEM");
     131        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     132
     133        info->domain_name = talloc_strdup(info, "NT AUTHORITY");
     134        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     135
     136        info->full_name = talloc_strdup(info, "System");
     137        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     138
     139        info->logon_script = talloc_strdup(info, "");
     140        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     141
     142        info->profile_path = talloc_strdup(info, "");
     143        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     144
     145        info->home_directory = talloc_strdup(info, "");
     146        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     147
     148        info->home_drive = talloc_strdup(info, "");
     149        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     150
     151        info->logon_server = talloc_strdup(info, netbios_name);
     152        NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
     153
     154        info->last_logon = 0;
     155        info->last_logoff = 0;
     156        info->acct_expiry = 0;
     157        info->last_password_change = 0;
     158        info->allow_password_change = 0;
     159        info->force_password_change = 0;
     160
     161        info->logon_count = 0;
     162        info->bad_password_count = 0;
     163
     164        info->acct_flags = ACB_NORMAL;
     165
     166        info->authenticated = true;
     167
     168        *_user_info_dc = user_info_dc;
    301169
    302170        return NT_STATUS_OK;
     
    304172
    305173
    306 /* Create server info for the Administrator account. This should only be used
    307  * during provisioning when we need to impersonate Administrator but
    308  * the account has not been created yet */
    309 
    310 static NTSTATUS create_admin_token(TALLOC_CTX *mem_ctx,
    311                                    struct dom_sid *user_sid,
    312                                    struct dom_sid *group_sid,
    313                                    int n_groupSIDs,
    314                                    struct dom_sid **groupSIDs,
    315                                    struct security_token **token)
    316 {
    317         struct security_token *ptoken;
    318         int i;
    319 
    320         ptoken = security_token_initialise(mem_ctx);
    321         NT_STATUS_HAVE_NO_MEMORY(ptoken);
    322 
    323         ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 3);
    324         NT_STATUS_HAVE_NO_MEMORY(ptoken->sids);
    325 
    326         ptoken->user_sid = talloc_reference(ptoken, user_sid);
    327         ptoken->group_sid = talloc_reference(ptoken, group_sid);
    328         ptoken->privilege_mask = 0;
    329 
    330         ptoken->sids[0] = ptoken->user_sid;
    331         ptoken->sids[1] = ptoken->group_sid;
    332         ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS);
    333         NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]);
    334         ptoken->num_sids = 3;
    335 
    336 
    337         for (i = 0; i < n_groupSIDs; i++) {
    338                 size_t check_sid_idx;
    339                 for (check_sid_idx = 1;
    340                      check_sid_idx < ptoken->num_sids;
    341                      check_sid_idx++) {
    342                         if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) {
    343                                 break;
    344                         }
    345                 }
    346 
    347                 if (check_sid_idx == ptoken->num_sids) {
    348                         ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]);
    349                 }
    350         }
    351 
    352         *token = ptoken;
    353         ptoken->privilege_mask = ~0;
    354         return NT_STATUS_OK;
    355 }
    356 
    357 static NTSTATUS auth_domain_admin_server_info(TALLOC_CTX *mem_ctx,
     174static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx,
    358175                                              const char *netbios_name,
    359176                                              const char *domain_name,
    360177                                              struct dom_sid *domain_sid,
    361                                               struct auth_serversupplied_info **_server_info)
    362 {
    363         struct auth_serversupplied_info *server_info;
    364 
    365         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    366         NT_STATUS_HAVE_NO_MEMORY(server_info);
    367 
    368         server_info->account_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINISTRATOR);
    369         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    370 
    371         server_info->primary_group_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS);
    372         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    373 
    374         server_info->n_domain_groups = 6;
    375         server_info->domain_groups = talloc_array(server_info, struct dom_sid *, server_info->n_domain_groups);
    376 
    377         server_info->domain_groups[0] = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS);
    378         server_info->domain_groups[1] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINS);
    379         server_info->domain_groups[2] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS);
    380         server_info->domain_groups[3] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
    381         server_info->domain_groups[4] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_POLICY_ADMINS);
    382         server_info->domain_groups[5] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
     178                                              struct auth_user_info_dc **_user_info_dc)
     179{
     180        struct auth_user_info_dc *user_info_dc;
     181        struct auth_user_info *info;
     182
     183        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     184        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     185
     186        user_info_dc->num_sids = 7;
     187        user_info_dc->sids = talloc_array(user_info_dc, struct dom_sid, user_info_dc->num_sids);
     188
     189        user_info_dc->sids[PRIMARY_USER_SID_INDEX] = *domain_sid;
     190        sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR);
     191
     192        user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid;
     193        sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS);
     194
     195        user_info_dc->sids[2] = global_sid_Builtin_Administrators;
     196
     197        user_info_dc->sids[3] = *domain_sid;
     198        sid_append_rid(&user_info_dc->sids[3], DOMAIN_RID_ADMINS);
     199        user_info_dc->sids[4] = *domain_sid;
     200        sid_append_rid(&user_info_dc->sids[4], DOMAIN_RID_ENTERPRISE_ADMINS);
     201        user_info_dc->sids[5] = *domain_sid;
     202        sid_append_rid(&user_info_dc->sids[5], DOMAIN_RID_POLICY_ADMINS);
     203        user_info_dc->sids[6] = *domain_sid;
     204        sid_append_rid(&user_info_dc->sids[6], DOMAIN_RID_SCHEMA_ADMINS);
    383205
    384206        /* What should the session key be?*/
    385         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    386         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    387 
    388         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    389         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    390 
    391         data_blob_clear(&server_info->user_session_key);
    392         data_blob_clear(&server_info->lm_session_key);
    393 
    394         server_info->account_name = talloc_strdup(server_info, "Administrator");
    395         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    396 
    397         server_info->domain_name = talloc_strdup(server_info, domain_name);
    398         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    399 
    400         server_info->full_name = talloc_strdup(server_info, "Administrator");
    401         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    402 
    403         server_info->logon_script = talloc_strdup(server_info, "");
    404         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    405 
    406         server_info->profile_path = talloc_strdup(server_info, "");
    407         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    408 
    409         server_info->home_directory = talloc_strdup(server_info, "");
    410         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    411 
    412         server_info->home_drive = talloc_strdup(server_info, "");
    413         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    414 
    415         server_info->logon_server = talloc_strdup(server_info, netbios_name);
    416         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server);
    417 
    418         server_info->last_logon = 0;
    419         server_info->last_logoff = 0;
    420         server_info->acct_expiry = 0;
    421         server_info->last_password_change = 0;
    422         server_info->allow_password_change = 0;
    423         server_info->force_password_change = 0;
    424 
    425         server_info->logon_count = 0;
    426         server_info->bad_password_count = 0;
    427 
    428         server_info->acct_flags = ACB_NORMAL;
    429 
    430         server_info->authenticated = true;
    431 
    432         *_server_info = server_info;
     207        user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     208        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
     209
     210        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     211        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
     212
     213        data_blob_clear(&user_info_dc->user_session_key);
     214        data_blob_clear(&user_info_dc->lm_session_key);
     215
     216        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     217        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     218
     219        info->account_name = talloc_strdup(info, "Administrator");
     220        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     221
     222        info->domain_name = talloc_strdup(info, domain_name);
     223        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     224
     225        info->full_name = talloc_strdup(info, "Administrator");
     226        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     227
     228        info->logon_script = talloc_strdup(info, "");
     229        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     230
     231        info->profile_path = talloc_strdup(info, "");
     232        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     233
     234        info->home_directory = talloc_strdup(info, "");
     235        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     236
     237        info->home_drive = talloc_strdup(info, "");
     238        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     239
     240        info->logon_server = talloc_strdup(info, netbios_name);
     241        NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
     242
     243        info->last_logon = 0;
     244        info->last_logoff = 0;
     245        info->acct_expiry = 0;
     246        info->last_password_change = 0;
     247        info->allow_password_change = 0;
     248        info->force_password_change = 0;
     249
     250        info->logon_count = 0;
     251        info->bad_password_count = 0;
     252
     253        info->acct_flags = ACB_NORMAL;
     254
     255        info->authenticated = true;
     256
     257        *_user_info_dc = user_info_dc;
    433258
    434259        return NT_STATUS_OK;
     
    438263                                               struct loadparm_context *lp_ctx,
    439264                                               struct dom_sid *domain_sid,
    440                                                struct auth_session_info **_session_info)
     265                                               struct auth_session_info **session_info)
    441266{
    442267        NTSTATUS nt_status;
    443         struct auth_serversupplied_info *server_info = NULL;
    444         struct auth_session_info *session_info = NULL;
     268        struct auth_user_info_dc *user_info_dc = NULL;
    445269        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
    446270
    447         nt_status = auth_domain_admin_server_info(mem_ctx, lp_netbios_name(lp_ctx),
    448                                                   lp_workgroup(lp_ctx), domain_sid,
    449                                                   &server_info);
     271        nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx),
     272                                                  lpcfg_workgroup(lp_ctx), domain_sid,
     273                                                  &user_info_dc);
    450274        if (!NT_STATUS_IS_OK(nt_status)) {
    451275                talloc_free(mem_ctx);
     
    453277        }
    454278
    455         session_info = talloc(mem_ctx, struct auth_session_info);
    456         NT_STATUS_HAVE_NO_MEMORY(session_info);
    457 
    458         session_info->server_info = talloc_reference(session_info, server_info);
    459 
    460         /* unless set otherwise, the session key is the user session
    461          * key from the auth subsystem */
    462         session_info->session_key = server_info->user_session_key;
    463 
    464         nt_status = create_admin_token(session_info,
    465                                        server_info->account_sid,
    466                                        server_info->primary_group_sid,
    467                                        server_info->n_domain_groups,
    468                                        server_info->domain_groups,
    469                                        &session_info->security_token);
    470         NT_STATUS_NOT_OK_RETURN(nt_status);
    471 
    472         session_info->credentials = cli_credentials_init(session_info);
    473         if (!session_info->credentials) {
    474                 return NT_STATUS_NO_MEMORY;
    475         }
    476 
    477         cli_credentials_set_conf(session_info->credentials, lp_ctx);
    478 
    479         *_session_info = session_info;
    480 
    481         return NT_STATUS_OK;
     279        nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc,
     280                                               AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS,
     281                                               session_info);
     282        /* There is already a reference between the sesion_info and user_info_dc */
     283        if (NT_STATUS_IS_OK(nt_status)) {
     284                talloc_steal(parent_ctx, *session_info);
     285        }
     286        talloc_free(mem_ctx);
     287        return nt_status;
    482288}
    483289
     
    495301        return session_info;
    496302}
     303
     304_PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx,
     305                                              struct loadparm_context *lp_ctx,
     306                                              struct auth_session_info **_session_info)
     307{
     308        NTSTATUS nt_status;
     309        struct auth_user_info_dc *user_info_dc = NULL;
     310        struct auth_session_info *session_info = NULL;
     311        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     312       
     313        nt_status = auth_anonymous_user_info_dc(mem_ctx,
     314                                               lpcfg_netbios_name(lp_ctx),
     315                                               &user_info_dc);
     316        if (!NT_STATUS_IS_OK(nt_status)) {
     317                talloc_free(mem_ctx);
     318                return nt_status;
     319        }
     320
     321        /* references the user_info_dc into the session_info */
     322        nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info);
     323        talloc_free(mem_ctx);
     324
     325        NT_STATUS_NOT_OK_RETURN(nt_status);
     326
     327        session_info->credentials = cli_credentials_init(session_info);
     328        if (!session_info->credentials) {
     329                return NT_STATUS_NO_MEMORY;
     330        }
     331
     332        cli_credentials_set_conf(session_info->credentials, lp_ctx);
     333        cli_credentials_set_anonymous(session_info->credentials);
     334       
     335        *_session_info = session_info;
     336
     337        return NT_STATUS_OK;
     338}
     339
     340_PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx,
     341                                    const char *netbios_name,
     342                                    struct auth_user_info_dc **_user_info_dc)
     343{
     344        struct auth_user_info_dc *user_info_dc;
     345        struct auth_user_info *info;
     346        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     347        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     348
     349        /* This returns a pointer to a struct dom_sid, which is the
     350         * same as a 1 element list of struct dom_sid */
     351        user_info_dc->num_sids = 1;
     352        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
     353        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
     354
     355        /* annoying, but the Anonymous really does have a session key... */
     356        user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     357        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
     358
     359        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     360        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
     361
     362        /*  and it is all zeros! */
     363        data_blob_clear(&user_info_dc->user_session_key);
     364        data_blob_clear(&user_info_dc->lm_session_key);
     365
     366        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     367        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     368
     369        info->account_name = talloc_strdup(info, "ANONYMOUS LOGON");
     370        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     371
     372        info->domain_name = talloc_strdup(info, "NT AUTHORITY");
     373        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     374
     375        info->full_name = talloc_strdup(info, "Anonymous Logon");
     376        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     377
     378        info->logon_script = talloc_strdup(info, "");
     379        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     380
     381        info->profile_path = talloc_strdup(info, "");
     382        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     383
     384        info->home_directory = talloc_strdup(info, "");
     385        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     386
     387        info->home_drive = talloc_strdup(info, "");
     388        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     389
     390        info->logon_server = talloc_strdup(info, netbios_name);
     391        NT_STATUS_HAVE_NO_MEMORY(info->logon_server);
     392
     393        info->last_logon = 0;
     394        info->last_logoff = 0;
     395        info->acct_expiry = 0;
     396        info->last_password_change = 0;
     397        info->allow_password_change = 0;
     398        info->force_password_change = 0;
     399
     400        info->logon_count = 0;
     401        info->bad_password_count = 0;
     402
     403        info->acct_flags = ACB_NORMAL;
     404
     405        info->authenticated = false;
     406
     407        *_user_info_dc = user_info_dc;
     408
     409        return NT_STATUS_OK;
     410}
     411
Note: See TracChangeset for help on using the changeset viewer.