Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
18 deleted
48 edited
13 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/auth/auth.h

    r414 r745  
    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
     26
    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;
     55
     56
    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, );
    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
     118
     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_);
     124
     125        NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, );
    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_;
     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
    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_);
     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
    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);
     207
    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_);
     213NTSTATUS auth_init(void);
    269214NTSTATUS auth_register(const struct auth_operations *ops);
     215
    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
     237
     238
     239
     240
     241
    287242
    288243NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx,
  • trunk/server/source4/auth/credentials/credentials.c

    r414 r745  
    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
    3231
    3332/**
     
    3837{
    3938        struct cli_credentials *cred = talloc(mem_ctx, struct cli_credentials);
    40         if (!cred) {
     39        if () {
    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
     51
    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
     58
     59
    6060        cred->old_password = NULL;
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     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
    72112
    73113        return cred;
     
    94134}
    95135
     136
     137
     138
     139
     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
     148
     149
    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)
     238)
    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
    205258                        return talloc_asprintf(mem_ctx, "%s@%s",
    206259                                               cli_credentials_get_username(cred),
    207260                                               cli_credentials_get_domain(cred));
    208261                } else {
     262
    209263                        return talloc_asprintf(mem_ctx, "%s@%s",
    210264                                               cli_credentials_get_username(cred),
     
    212266                }
    213267        }
     268
    214269        return talloc_reference(mem_ctx, cred->principal);
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
    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, lp_workgroup(lp_ctx), CRED_UNINITIALISED);
     684        cli_credentials_set_workstation(cred, lp_netbios_name(lp_ctx), CRED_UNINITIALISED);
     685        cli_credentials_set_realm(cred, lp_realm(lp_ctx), CRED_UNINITIALISED);
    619686}
    620687
     
    629696{
    630697        char *p;
     698
    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
     766
     767
     768
     769
     770
     771
     772
     773
     774
     775
     776
     777
     778
     779
     780
    693781}
    694782
     
    723811        const char *username;
    724812       
     813
     814
     815
     816
     817
    725818        if (cred->machine_account_pending) {
    726819                cli_credentials_set_machine_account(cred,
     
    760853        return (cred->tries > 0);
    761854}
     855
     856
     857
     858
     859
     860
     861
     862
     863
     864
     865
     866
     867
     868
     869
     870
     871
     872
     873
     874
     875
     876
     877
     878
     879
     880
     881
     882
     883
     884
     885
     886
     887
     888
     889
     890
     891
     892
     893
     894
     895
     896
     897
     898
     899
     900
     901
     902
     903
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913
     914
     915
     916
     917
     918
     919
     920
     921
     922
     923
     924
     925
     926
     927
     928
     929
     930
     931
     932
     933
     934
     935
     936
     937
     938
     939
     940
     941
     942
     943
     944
     945
     946
     947
     948
     949
     950
     951
     952
     953
     954
     955
     956
     957
     958
     959
     960
     961
     962
     963
     964
     965
     966
     967
     968
     969
     970
     971
     972
     973
     974
     975
     976
     977
     978
     979
     980
     981
     982
     983
     984
     985
     986
     987
     988
     989
     990
     991
     992
     993
     994
     995
     996
     997
     998
     999
     1000
  • trunk/server/source4/auth/credentials/credentials.h

    r414 r745  
    4545};
    4646
     47
     48
     49
     50
     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
    108117
    109118        struct smb_krb5_context *smb_krb5_context;
     
    120129        enum credentials_use_kerberos use_kerberos;
    121130
     131
     132
     133
    122134        /* gensec features which should be used for connections */
    123135        uint32_t gensec_features;
     
    131143
    132144struct ldb_context;
     145
    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);
     203
     204
    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);
     231
     232
    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);
     253
    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);
     280
     281
     282
     283
     284
    263285enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
     286
    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__ */
  • trunk/server/source4/auth/credentials/credentials_krb5.c

    r414 r745  
    2828#include "auth/credentials/credentials_proto.h"
    2929#include "auth/credentials/credentials_krb5.h"
     30
     31
    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
     61
     62
     63
     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 _ctx,
     134                        ,
     135                       
     136                        )
    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
    148155                talloc_free(ccc);
    149156                return ret;
     
    151158        if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
    152159                talloc_free(ccc);
     160
    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
    260284       
    261285        if (cred->machine_account_pending) {
     
    269293        }
    270294        if (cli_credentials_is_anonymous(cred)) {
     295
    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, );
     300        if (ret) {
     301                return ret;
     302        }
     303
     304        ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, );
    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
     362
     363
     364
     365
     366
     367
     368
     369
     370
     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);
    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
    377433                return ENOMEM;
    378434        }
     
    380436        maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
    381437                                        &gcc->creds);
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
    382455        if (maj_stat) {
    383456                talloc_free(gcc);
     
    387460                        ret = EINVAL;
    388461                }
     462
    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
    420496                        return ret;
    421497                }
     
    433509                        ret = EINVAL;
    434510                }
     511
    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
     567
     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);
    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,
    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
     713
     714
     715
     716
     717
     718
     719
     720
     721
     722
     723
    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
    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
  • trunk/server/source4/auth/credentials/credentials_krb5.h

    r414 r745  
    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       
     54
     55
     56
    4757#endif /* __CREDENTIALS_KRB5_H__ */
  • trunk/server/source4/auth/credentials/credentials_ntlm.c

    r414 r745  
    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,
  • trunk/server/source4/auth/credentials/pycredentials.c

    r414 r745  
    1717*/
    1818
     19
    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
     196
     197
     198
     199
     200
     201
     202
     203
     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
     211
     212
     213
     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
     243
     244
     245
     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
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
    232355
    233356static PyMethodDef py_creds_methods[] = {
     
    285408        { "set_kerberos_state", (PyCFunction)py_creds_set_kerberos_state, METH_VARARGS,
    286409                NULL },
     410
     411
    287412        { "guess", (PyCFunction)py_creds_guess, METH_VARARGS, NULL },
    288413        { "set_machine_account", (PyCFunction)py_creds_set_machine_account, METH_VARARGS, NULL },
     414
     415
     416
    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
     429
     430
     431
     432
     433
     434
    301435void initcredentials(void)
    302436{
    303437        PyObject *m;
     438
     439
     440
     441
     442
    304443
    305444        if (PyType_Ready(&PyCredentials) < 0)
     445
     446
     447
    306448                return;
    307449
     
    314456        PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
    315457
     458
     459
     460
     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}
  • trunk/server/source4/auth/credentials/pycredentials.h

    r414 r745  
    2121
    2222#include "auth/credentials/credentials.h"
    23 #include "pytalloc.h"
     23#include
    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)
  • trunk/server/source4/auth/credentials/tests/simple.c

    r414 r745  
    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);
  • trunk/server/source4/auth/gensec/cyrus_sasl.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "auth/auth.h"
     23#include ".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
    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        (gensec_security);
     122        (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(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 (_addr) {
     158                local_addr = talloc_asprintf(gensec_sasl_state,
     159                                "%s;%d",
     160                               
     161                                );
     162        }
     163
     164        if (_addr) {
     165                remote_addr = talloc_asprintf(gensec_sasl_state,
     166                                "%s;%d",
     167                               
     168                                );
    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
     185
     186
    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) {
  • trunk/server/source4/auth/gensec/gensec.c

    r414 r745  
    2222
    2323#include "includes.h"
    24 #include "auth/auth.h"
     24#include ".h"
    2525#include "lib/events/events.h"
     26
     27
     28
    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
    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 lp_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 of the
    506511  @ gensec_security return
    507512*/
     
    517522        }
    518523
    519         (*gensec_security) = talloc(mem_ctx, struct gensec_security);
     524        (*gensec_security) = talloc(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(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
     1316
     1317
     1318
     1319
     1320
     1321
     1322
     1323
     1324
     1325
     1326
     1327
     1328
     1329
     1330
     1331
     1332
     1333
     1334
     1335
     1336
     1337
     1338
     1339
    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 lp_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 lp_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        sort_gensec);
    13291427       
    13301428        return NT_STATUS_OK;
  • trunk/server/source4/auth/gensec/gensec.h

    r414 r745  
    2727#include "libcli/util/ntstatus.h"
    2828
     29
     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 _addr;
    173163        struct gensec_settings *settings;
    174164       
     
    191181struct socket_context;
    192182struct auth_context;
     183
    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
     315
     316
    318317#endif /* __GENSEC_H__ */
  • trunk/server/source4/auth/gensec/gensec.pc.in

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

    r414 r745  
    2828#include "librpc/gen_ndr/krb5pac.h"
    2929#include "auth/auth.h"
    30 #include "lib/ldb/include/ldb.h"
     30#include
    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
    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        ;
     151
     152        gensec_gssapi_state = talloc(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
     162
     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
    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
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     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
    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        principal = gensec_get_target_principal(gensec_security);
     342        if () {
    350343                name_type = GSS_C_NULL_OID;
    351344        } else {
    352                 principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",
     345               
    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);
     348
     349                name_type = GSS_C_NT_E;
     350        }
     351        name_token.value  = discard_const_p(uint8_t, principal);
     352        name_token.length = strlen(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);
    376369        switch (ret) {
    377370        case 0:
    378371                break;
    379372        case KRB5KDC_ERR_PREAUTH_FAILED:
     373
     374
    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));
    386385                return NT_STATUS_UNSUCCESSFUL;
    387386        }
     
    460459                case GENSEC_CLIENT:
    461460                {
     461
     462
     463
     464
     465
     466
     467
     468
     469
     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
     490
     491
     492
     493
     494
     495
     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 cryptographicly 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 cryptographicly 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
     561
     562
     563
     564
     565
     566
     567
     568
     569
    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 () {
     647                                if () {
    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 cryptographicly 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 cryptographicly 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 cryptographicly 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 cryptographicly 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 cryptographicly 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_ = 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
     1266
    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_
    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 into the session_info */
     1367        nt_status =
     1368                                        , &session_info);
    13271369        if (!NT_STATUS_IS_OK(nt_status)) {
    13281370                talloc_free(mem_ctx);
     
    13361378        }
    13371379
     1380
     1381
     1382
     1383
     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
     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);
    13581407                if (ret) {
    13591408                        talloc_free(mem_ctx);
     1409
    13601410                        return NT_STATUS_NO_MEMORY;
    13611411                }
  • trunk/server/source4/auth/gensec/gensec_gssapi.h

    r414 r745  
    6565        int gss_exchange_count;
    6666        size_t sig_size;
     67
     68
    6769};
    6870
  • trunk/server/source4/auth/gensec/gensec_krb5.c

    r414 r745  
    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
    3432#include "librpc/rpc/dcerpc.h"
    3533#include "auth/credentials/credentials.h"
    3634#include "auth/credentials/credentials_krb5.h"
     35
    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
    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 _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                                     
     196                                     _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
    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);
    267286        switch (ret) {
    268287        case 0:
    269288                break;
    270289        case KRB5KDC_ERR_PREAUTH_FAILED:
     290
    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_));
    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
     336
    304337        switch (ret) {
    305338        case 0:
     
    459492                struct keytab_container *keytab;
    460493                krb5_principal server_in_keytab;
     494
     495
    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);
    478512
    479513                if (ret) {
     514
    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_ = 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
    603639                talloc_free(mem_ctx);
    604640                return NT_STATUS_NO_MEMORY;
     
    614650                          smb_get_krb5_error_message(context,
    615651                                                     ret, mem_ctx)));
     652
    616653                krb5_free_principal(context, client_principal);
    617                 free(principal_string);
     654                );
    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_
    630667                                                                                             gensec_security->auth_context,
    631668                                                                                             principal_string,
    632                                                                                              &server_info);
     669                                                                                             );
    633670                        if (!NT_STATUS_IS_OK(nt_status)) {
     671
     672
    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
     680
     681
    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
    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
     706
    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_
    679713                                                                 NULL,
    680714                                                                 3, &validation,
    681                                                                  &server_info);
     715                                                                 &
    682716                if (!NT_STATUS_IS_OK(nt_status)) {
     717
     718
    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)) {
  • trunk/server/source4/auth/gensec/pygensec.c

    r414 r745  
    1717*/
    1818
     19
    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
    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 = );
    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
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     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        );
    88126        if (!NT_STATUS_IS_OK(status)) {
    89127                PyErr_SetNTSTATUS(status);
     
    91129                return NULL;
    92130        }
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
    93141        return (PyObject *)self;
    94142}
    95143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     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
     255
     256
     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
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
     412
     413
     414
     415
     416
     417
     418
     419
     420
     421
     422
     423
     424
     425
     426
     427
     428
     429
     430
     431
     432
     433
     434
     435
     436
     437
     438
     439
     440
     441
     442
     443
     444
     445
     446
     447
     448
     449
     450
     451
     452
     453
     454
     455
     456
     457
    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
     477
     478
     479
     480
     481
     482
     483
     484
     485
     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
     497
    131498void initgensec(void)
    132499{
    133500        PyObject *m;
     501
     502
     503
     504
    134505
    135506        if (PyType_Ready(&Py_Security) < 0)
     
    140511                return;
    141512
     513
     514
     515
     516
     517
     518
     519
     520
     521
    142522        Py_INCREF(&Py_Security);
    143523        PyModule_AddObject(m, "Security", (PyObject *)&Py_Security);
  • trunk/server/source4/auth/gensec/schannel.c

    r414 r745  
    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_(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
  • trunk/server/source4/auth/gensec/socket.c

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

    r414 r745  
    2929#include "auth/gensec/gensec.h"
    3030#include "auth/gensec/gensec_proto.h"
     31
    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               
     424               
     425                        ) {
    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
     515
    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();
    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
  • trunk/server/source4/auth/kerberos/kerberos.c

    r414 r745  
    3434  This version is built to use a keyblock, rather than needing the
    3535  original password.
     36
     37
     38
     39
    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, 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 [email protected]
     81
     82
     83
     84
     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
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
    129164        return 0;
    130165}
  • trunk/server/source4/auth/kerberos/kerberos.h

    r414 r745  
    2424#include "librpc/gen_ndr/krb5pac.h"
    2525
    26 struct auth_serversupplied_info;
     26struct auth_;
    2727struct cli_credentials;
    2828
     
    5353#define KRB5_KEY_DATA(k)        ((k)->contents)
    5454#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */
     55
     56
     57
    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;
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
    150156
    151157#include "auth/kerberos/proto.h"
  • trunk/server/source4/auth/kerberos/kerberos_pac.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
    44   Create and parse the krb5 PAC
    5    
     5
    66   Copyright (C) Andrew Bartlett <[email protected]> 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
    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        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
    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_, &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_);
    771764        krb5_pac_free(context, pac);
    772765        if (ret) {
  • trunk/server/source4/auth/kerberos/kerberos_util.c

    r414 r745  
    2727#include "auth/credentials/credentials_proto.h"
    2828#include "auth/credentials/credentials_krb5.h"
     29
     30
     31
     32
    2933
    3034struct principal_container {
    3135        struct smb_krb5_context *smb_krb5_context;
    3236        krb5_principal principal;
     37
    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
    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
    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
     254
    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                                         
    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        );
    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
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
    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;
    152342        time_t kdc_time = 0;
    153343        krb5_principal princ;
     344
    154345        int tries;
    155346        TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
     347
    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
     361
     362
     363
     364
     365
     366
     367
    167368        password = cli_credentials_get_password(credentials);
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
    168393
    169394        tries = 2;
    170395        while (tries--) {
     396
     397
     398
     399
     400
     401
     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
    198441
    199442                if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) {
     
    207450        }
    208451
     452
     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               
     456                       
     457                       
     458                                                ));
    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               
     482                       
     483                       
     484                                                ));
    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
    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                "failed to open keytab for read of old entries: %s\n",
     703                       
     704                                                ));
    528705                talloc_free(mem_ctx);
    529706                return ret;
     
    531708
    532709        while (!ret) {
     710
     711
    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
     820
     821
     822
     823
     824
     825
     826
     827
     828
     829
     830
     831
     832
     833
     834
     835
     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
     862
    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
    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}
  • trunk/server/source4/auth/kerberos/krb5_init_context.c

    r414 r745  
    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
    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        );
    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(, ("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
    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();
    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();
    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();
    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();
    334347                                return EINVAL;
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
    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();
    351386                        return ret;
    352387                }
    353388                talloc_free(smb_krb5);
    354                
     389
    355390                break;
    356391        }
     392
    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                                     
    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(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       
     509               
     510               
     511       
     512               
     513                        );
     514                ;
     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                                           lp_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));
    474525
    475526        return 0;
    476527}
    477528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
     576
     577
     578
     579
     580
     581
  • trunk/server/source4/auth/kerberos/krb5_init_context.h

    r414 r745  
    2121        krb5_context krb5_context;
    2222        krb5_log_facility *logf;
     23
    2324};
    2425       
    2526struct tevent_context;
    2627struct loadparm_context;
     28
     29
     30
     31
     32
     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,
  • trunk/server/source4/auth/ntlm/auth.c

    r414 r745  
    2020
    2121#include "includes.h"
     22
     23
    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
     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, )
    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) {
    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                ;
    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__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_);
    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 struct.
     137 *
     138 * The return value takes precedence over the contents of the
    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 structure
     150 *
     151 * @param
    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_ {
    207191        struct auth_context *auth_ctx;
    208192        const struct auth_usersupplied_info *user_info;
    209         struct auth_serversupplied_info *server_info;
     193        struct auth_;
    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 struct.
     206 *
     207 * The return value takes precedence over the contents of the
    234208 * struct.  When the return is other than NT_STATUS_OK the contents
    235209 * of that structure is undefined.
     210
     211
     212
     213
    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
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
    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
    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
     367 *
     368 * @param mem_ctx The parent memory context for the structure
     369 *
     370 * @param
    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 *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
    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
     488
     489
     490
     491
     492
     493
     494
     495
     496
     497
     498
     499
     500
     501
     502
     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_)
    548629        };
    549630
     
    551632}
    552633
    553 _PUBLIC_ NTSTATUS auth_init(void)
     634_PUBLIC_ NTSTATUS auth_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 }
  • trunk/server/source4/auth/ntlm/auth_anonymous.c

    r414 r745  
    5353                                         TALLOC_CTX *mem_ctx,
    5454                                         const struct auth_usersupplied_info *user_info,
    55                                          struct auth_serversupplied_info **_server_info)
     55                                         struct auth_)
    5656{
    57         return auth_anonymous_server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), _server_info);
     57        return auth_anonymous_);
    5858}
    5959
  • trunk/server/source4/auth/ntlm/auth_developer.c

    r414 r745  
    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_)
    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_)
    178174{
    179175        /* don't handle any users */
  • trunk/server/source4/auth/ntlm/auth_sam.c

    r414 r745  
    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
     35
    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                                             lp_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                                             lp_lanman_auth(auth_context->lp_ctx),
     114                                                 lp_ntlm_auth(auth_context->lp_ctx),
    113115                                             user_info->logon_parameters,
    114116                                             &auth_context->challenge.data,
     
    135137
    136138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     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(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
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     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,
    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_)
    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
     250
     251
     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, 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, 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_
     284_sam_name(ctx->auth_ctx->lp_ctx),
    235285                                             domain_dn,
    236286                                             msg,
    237287                                             user_sess_key, lm_sess_key,
    238                                              server_info);
     288                                             );
    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, *);
    245295        talloc_free(tmp_ctx);
    246296
     
    272322        }
    273323
    274         is_local_name = lp_is_myname(ctx->auth_ctx->lp_ctx,
     324        is_local_name = lp
    275325                                  user_info->mapped.domain_name);
    276         is_my_domain  = lp_is_mydomain(ctx->auth_ctx->lp_ctx,
     326        is_my_domain  = lp
    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 (lp_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: lp_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_
    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_
    366380};
    367381
  • trunk/server/source4/auth/ntlm/auth_server.c

    r414 r745  
    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, )
    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        lp_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 = lp
    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 = lp
     67        io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx);
     68        io.in.gensec_settings = lp_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                                        lp_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_)
    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 = lp_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;
  • trunk/server/source4/auth/ntlm/auth_simple.c

    r414 r745  
    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
    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_;
    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(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, &);
    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)) {
  • trunk/server/source4/auth/ntlm/auth_unix.c

    r414 r745  
    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_(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_);
    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, "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                );
     61                NT_STATUS_HAVE_NO_MEMORY();
    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, 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, "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, lp_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 = lp_passwordlevel(lp_ctx);
    607614
    608615        *ret_passwd = NULL;
     
    707714
    708715        if (crypted[0] == '\0') {
    709                 if (!lp_null_passwords(lp_ctx)) {
     716                if (!lp_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_)
    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__netbios_name(ctx->auth_ctx->lp_ctx),
     823                                              user_info, pwd, );
    817824        if (!NT_STATUS_IS_OK(nt_status)) {
    818825                talloc_free(check_ctx);
  • trunk/server/source4/auth/ntlm/auth_util.c

    r414 r745  
    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, )
    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(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                        ;
    130126                        DATA_BLOB chall_blob;
    131                         user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info);
     127                        user_info_temp = talloc(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, );
    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 (lp_client_ntlmv2_auth(auth_context->lp_ctx)) {
     144                                DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lp_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 (lp_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(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 }
  • trunk/server/source4/auth/ntlm/auth_winbind.c

    r414 r745  
    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
     41
     42
     43
     44
    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, 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, sid, NULL,
    10988                          &info3->base.primary_gid);
    11089
     
    11796
    11897        for (i = 2, j = 0; i < info->num_sids; ++i, ++j) {
     98
     99
     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_)
    237135{
    238136        NTSTATUS status;
    239         struct server_id *winbind_servers;
     137        struct ;
    240138        struct winbind_check_password_state *s;
    241139        const struct auth_usersupplied_info *user_info_new;
    242140        struct netr_IdentityInfo *identity_info;
    243141
     142
     143
     144
     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                ;
    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, );
    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__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                                                      );
    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_)
    332235{
    333236        struct wbcAuthUserParams params;
     
    382285
    383286        wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
    384         if (!WBC_ERROR_IS_OK(wbc_status)) {
     287        if () {
    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__netlogon_validation(mem_ctx,
    400305                                        user_info->client.account_name,
    401                                         3, &validation, server_info);
     306                                        3, &validation, );
    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)) {
  • trunk/server/source4/auth/ntlmssp/ntlmssp.c

    r414 r745  
    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        = 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        = 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,
    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(
    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                 
    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      =
    409278        .auth_type      = DCERPC_AUTH_TYPE_NTLMSSP,
    410279        .oid            = gensec_ntlmssp_oids,
  • trunk/server/source4/auth/ntlmssp/ntlmssp.h

    r414 r745  
    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
    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_;
    15031};
    15132
     
    15334struct auth_session_info;
    15435
     36
     37
    15538#include "auth/ntlmssp/proto.h"
  • trunk/server/source4/auth/ntlmssp/ntlmssp_client.c

    r414 r745  
    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
    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
    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        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->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 (lp_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 ((
     240            && lp_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(
    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        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 ;
     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        _client_ntlmv2_auth(gensec_security->settings->lp_ctx);
     346
     347        ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     348
     349       
    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               
    331355        }
    332356
    333357        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
    334                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
     358               
    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               
    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               
    347371        }
    348372
    349373        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
    350                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
     374               
    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;
  • trunk/server/source4/auth/ntlmssp/ntlmssp_server.c

    r414 r745  
    2424#include "includes.h"
    2525#include "system/network.h"
     26
    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
    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, _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 
  • trunk/server/source4/auth/ntlmssp/ntlmssp_sign.c

    r414 r745  
    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 <[email protected]> 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
    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 *
    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 *
    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 
  • trunk/server/source4/auth/pyauth.c

    r414 r745  
    22   Unix SMB/CIFS implementation.
    33   Copyright (C) Jelmer Vernooij <[email protected]> 2007-2008
    4    
     4   Copyright (C) Andrew Bartlett <[email protected]> 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
    1921#include "includes.h"
     22
    2023#include "param/param.h"
    2124#include "pyauth.h"
     25
    2226#include "auth/system_session_proto.h"
     27
    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_,
    33108};
    34109
     
    43118        struct loadparm_context *lp_ctx = NULL;
    44119        struct auth_session_info *session;
     120
    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
     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
    91177
    92178        return PyAuthSession_FromSession(session);
    93179}
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     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
    99372        { NULL },
    100373};
     
    104377        PyObject *m;
    105378
     379
     380
     381
     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}
  • trunk/server/source4/auth/pyauth.h

    r414 r745  
    2121#define _PYAUTH_H_
    2222
    23 #include "pytalloc.h"
     23#include
    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)
  • trunk/server/source4/auth/sam.c

    r414 r745  
    22   Unix SMB/CIFS implementation.
    33   Password and authentication handling
    4    Copyright (C) Andrew Bartlett <[email protected]> 2001-2004
     4   Copyright (C) Andrew Bartlett <[email protected]> 2001-20
    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
     42
    4443        "supplementalCredentials",              \
    4544                                                \
     
    5251                                                \
    5352        "pwdLastSet",                           \
    54         "accountExpires"                       
     53        "accountExpires"
    5554
    5655const char *krbtgt_attrs[] = {
    57         KRBTGT_ATTRS
     56        KRBTGT_ATTRS
    5857};
    5958
    6059const char *server_attrs[] = {
    61         KRBTGT_ATTRS
     60        KRBTGT_ATTRS
    6261};
    6362
     
    7069        "userWorkstations",
    7170                       
    72         /* required for server_info, not access control: */
     71        /* required for , 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 va
    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 = _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(,("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(,("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(,("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(
    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(
    214213                         name_for_logs));
    215                 DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n",
     214                DEBUG(
    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_;
     282        ;
     283        ;
    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();
    411313                return status;
    412314        }
    413315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     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        _uint(msg, "logonCount", 0);
     416        _uint(msg, "badPwdCount",
    501417                0);
    502418
    503         server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,
     419       
    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 = , user_dn,
     495                , "(objectClass=*)");
    543496        if (ret != LDB_SUCCESS) {
    544497                talloc_free(tmp_ctx);
     
    551504        return NT_STATUS_OK;
    552505}
     506
     507
     508
     509
     510
     511
     512
     513
     514
     515
     516
     517
     518
     519
     520
     521
     522
     523
     524
     525
     526
     527
     528
     529
     530
     531
     532
     533
     534
     535
     536
     537
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
     549
     550
     551
     552
     553
     554
     555
     556
     557
     558
     559
     560
     561
     562
     563
     564
     565
     566
     567
     568
     569
     570
     571
     572
     573
     574
     575
     576
     577
     578
     579
     580
     581
     582
     583
     584
     585
     586
     587
  • trunk/server/source4/auth/samba_server_gensec.c

    r414 r745  
    3939        struct gensec_security *gensec_ctx;
    4040        struct auth_context *auth_context;
     41
     42
     43
     44
     45
    4146       
    42         nt_status = auth_context_create(mem_ctx,
     47        nt_status = auth_context_create(
    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
    5056                return nt_status;
    5157        }
    5258
    53         nt_status = gensec_server_start(mem_ctx,
     59        nt_status = gensec_server_start(
    5460                                        event_ctx,
    55                                         lp_gensec_settings(mem_ctx, lp_ctx),
     61                                        lp_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();
    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}
  • trunk/server/source4/auth/session.c

    r414 r745  
    33   Authentication utility functions
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    Copyright (C) Andrew Bartlett 2001
     5   Copyright (C) Andrew Bartlett 2001
    66   Copyright (C) Jeremy Allison 2000-2001
    77   Copyright (C) Rafal Szczesniak 2002
     
    2424#include "includes.h"
    2525#include "auth/auth.h"
     26
     27
     28
    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
     34
    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);
    183149
    184150        session_info->credentials = NULL;
    185151
     152
    186153        *_session_info = session_info;
     154
    187155        return NT_STATUS_OK;
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
     181
     182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
     299
     300
     301
     302
     303
     304
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
    188337}
    189338
     
    199348        }
    200349
    201         security_token_debug(dbg_lev, session_info->security_token);
    202 }
    203 
     350        security_token_debug(dbg_lev, session_info->security_token);
     351}
     352
  • trunk/server/source4/auth/session.h

    r414 r745  
    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
    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
  • trunk/server/source4/auth/system_session.c

    r414 r745  
    33   Authentication utility functions
    44   Copyright (C) Andrew Tridgell 1992-1998
    5    Copyright (C) Andrew Bartlett 2001
     5   Copyright (C) Andrew Bartlett 2001
    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_ */
    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                                             &s);
    16157        if (!NT_STATUS_IS_OK(nt_status)) {
     58
     59
    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        ;
     63        return static_session;
     64}
     65
     66NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx,
     67                               
     68                                  struct auth_session_info **_session_info)
    17169{
    17270        NTSTATUS nt_status;
    173         struct auth_serversupplied_info *server_info = NULL;
     71        struct auth_ = 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__netbios_name(lp_ctx),
     76                                            &);
    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 into the session_info */
     83        nt_status = , &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__netbios_name(lp_ctx),
     272                                                  lp_workgroup(lp_ctx), domain_sid,
     273                                                  &);
    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
     305
     306
     307
     308
     309
     310
     311
     312
     313
     314
     315
     316
     317
     318
     319
     320
     321
     322
     323
     324
     325
     326
     327
     328
     329
     330
     331
     332
     333
     334
     335
     336
     337
     338
     339
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
     382
     383
     384
     385
     386
     387
     388
     389
     390
     391
     392
     393
     394
     395
     396
     397
     398
     399
     400
     401
     402
     403
     404
     405
     406
     407
     408
     409
     410
     411
Note: See TracChangeset for help on using the changeset viewer.