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:
3 deleted
9 edited
3 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

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

    r414 r745  
    4545};
    4646
     47enum credentials_krb_forwardable {
     48        CRED_AUTO_KRB_FORWARDABLE = 0, /* Default, follow library defaults */
     49        CRED_NO_KRB_FORWARDABLE,       /* not forwardable */
     50        CRED_FORCE_KRB_FORWARDABLE     /* forwardable */
     51};
     52
    4753#define CLI_CRED_NTLM2       0x01
    4854#define CLI_CRED_NTLMv2_AUTH 0x02
     
    7783        const char *realm;
    7884        const char *principal;
    79         const char *salt_principal;
     85        char *salt_principal;
     86        char *impersonate_principal;
     87        char *target_service;
    8088
    8189        const char *bind_dn;
     
    106114        enum netr_SchannelType secure_channel_type;
    107115        int kvno;
     116        time_t password_last_changed_time;
    108117
    109118        struct smb_krb5_context *smb_krb5_context;
     
    120129        enum credentials_use_kerberos use_kerberos;
    121130
     131        /* Should we get a forwardable ticket? */
     132        enum credentials_krb_forwardable krb_forwardable;
     133
    122134        /* gensec features which should be used for connections */
    123135        uint32_t gensec_features;
     
    131143
    132144struct ldb_context;
     145struct ldb_message;
    133146struct loadparm_context;
    134147struct ccache_container;
     
    156169const char *cli_credentials_get_username(struct cli_credentials *cred);
    157170int cli_credentials_get_krb5_context(struct cli_credentials *cred,
    158                                      struct tevent_context *event_ctx,
    159171                                     struct loadparm_context *lp_ctx,
    160172                                     struct smb_krb5_context **smb_krb5_context);
     
    162174                               struct tevent_context *event_ctx,
    163175                               struct loadparm_context *lp_ctx,
    164                                struct ccache_container **ccc);
     176                               struct ccache_container **ccc,
     177                               const char **error_string);
     178int cli_credentials_get_named_ccache(struct cli_credentials *cred,
     179                                     struct tevent_context *event_ctx,
     180                                     struct loadparm_context *lp_ctx,
     181                                     char *ccache_name,
     182                                     struct ccache_container **ccc, const char **error_string);
    165183int cli_credentials_get_keytab(struct cli_credentials *cred,
    166                                struct tevent_context *event_ctx,
    167184                               struct loadparm_context *lp_ctx,
    168185                               struct keytab_container **_ktc);
     
    175192const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx);
    176193int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
    177                                          struct tevent_context *event_ctx,
    178194                                         struct loadparm_context *lp_ctx,
    179195                                         struct gssapi_creds_container **_gcc);
     
    181197                                         struct tevent_context *event_ctx,
    182198                                         struct loadparm_context *lp_ctx,
    183                                          struct gssapi_creds_container **_gcc);
     199                                         struct gssapi_creds_container **_gcc,
     200                                         const char **error_string);
    184201void cli_credentials_set_kerberos_state(struct cli_credentials *creds,
    185202                                        enum credentials_use_kerberos use_kerberos);
     203void cli_credentials_set_krb_forwardable(struct cli_credentials *creds,
     204                                         enum credentials_krb_forwardable krb_forwardable);
    186205bool cli_credentials_set_domain(struct cli_credentials *cred,
    187206                                const char *val,
     
    210229void cli_credentials_set_secure_channel_type(struct cli_credentials *cred,
    211230                                     enum netr_SchannelType secure_channel_type);
     231void cli_credentials_set_password_last_changed_time(struct cli_credentials *cred,
     232                                                             time_t last_change_time);
    212233void cli_credentials_set_netlogon_creds(struct cli_credentials *cred,
    213234                                        struct netlogon_creds_CredentialState *netlogon_creds);
     
    215236                                          struct smb_krb5_context *smb_krb5_context);
    216237NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred,
    217                                               struct tevent_context *event_ctx,
    218238                                              struct loadparm_context *lp_ctx,
    219239                                              const char *serviceprincipal);
     
    231251                                           const char *(*password_cb) (struct cli_credentials *));
    232252enum netr_SchannelType cli_credentials_get_secure_channel_type(struct cli_credentials *cred);
     253time_t cli_credentials_get_password_last_changed_time(struct cli_credentials *cred);
    233254void cli_credentials_set_kvno(struct cli_credentials *cred,
    234255                              int kvno);
     
    241262                                       enum credentials_obtained obtained);
    242263int cli_credentials_set_keytab_name(struct cli_credentials *cred,
    243                                     struct tevent_context *event_ctx,
    244264                                    struct loadparm_context *lp_ctx,
    245265                                    const char *keytab_name,
    246266                                    enum credentials_obtained obtained);
    247 int cli_credentials_update_keytab(struct cli_credentials *cred,
    248                                   struct tevent_context *event_ctx,
    249                                   struct loadparm_context *lp_ctx);
    250267void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features);
    251268uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds);
    252269int cli_credentials_set_ccache(struct cli_credentials *cred,
    253                                struct tevent_context *event_ctx,
    254270                               struct loadparm_context *lp_ctx,
    255271                               const char *name,
    256                                enum credentials_obtained obtained);
     272                               enum credentials_obtained obtained,
     273                               const char **error_string);
    257274bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained);
    258275bool cli_credentials_parse_password_fd(struct cli_credentials *credentials,
     
    261278                                       enum credentials_obtained obtained);
    262279void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal);
     280void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal);
     281void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal);
     282const char *cli_credentials_get_salt_principal(struct cli_credentials *cred);
     283const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred);
     284const char *cli_credentials_get_target_service(struct cli_credentials *cred);
    263285enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds);
     286enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds);
    264287NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
    265                                      struct tevent_context *event_ctx,
    266288                                     struct loadparm_context *lp_ctx,
    267289                                     struct ldb_context *ldb,
    268290                                     const char *base,
    269                                      const char *filter);
     291                                     const char *filter,
     292                                     char **error_string);
    270293 int cli_credentials_get_kvno(struct cli_credentials *cred);
    271294
     295
    272296#endif /* __CREDENTIALS_H__ */
  • 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#include "auth/kerberos/kerberos_credentials.h"
     31#include "auth/kerberos/kerberos_util.h"
    3032#include "param/param.h"
    3133
    3234_PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
    33                                               struct tevent_context *event_ctx,
    3435                                     struct loadparm_context *lp_ctx,
    3536                                     struct smb_krb5_context **smb_krb5_context)
     
    4142        }
    4243
    43         ret = smb_krb5_init_context(cred, event_ctx, lp_ctx, &cred->smb_krb5_context);
     44        ret = smb_krb5_init_context(cred, NULL, lp_ctx,
     45                                    &cred->smb_krb5_context);
    4446        if (ret) {
    4547                cred->smb_krb5_context = NULL;
     
    5052}
    5153
    52 /* This needs to be called directly after the cli_credentials_init(),
    53  * otherwise we might have problems with the krb5 context already
    54  * being here.
     54/* For most predictable behaviour, this needs to be called directly after the cli_credentials_init(),
     55 * otherwise we may still have references to the old smb_krb5_context in a credential cache etc
    5556 */
    5657_PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred,
    5758                                          struct smb_krb5_context *smb_krb5_context)
    5859{
     60        if (smb_krb5_context == NULL) {
     61                talloc_unlink(cred, cred->smb_krb5_context);
     62                cred->smb_krb5_context = NULL;
     63                return NT_STATUS_OK;
     64        }
     65
    5966        if (!talloc_reference(cred, smb_krb5_context)) {
    6067                return NT_STATUS_NO_MEMORY;
     
    6572
    6673static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
    67                                     struct ccache_container *ccache,
    68                                     enum credentials_obtained obtained)
     74                                           struct ccache_container *ccache,
     75                                           enum credentials_obtained obtained,
     76                                           const char **error_string)
    6977{
    7078       
     
    8189
    8290        if (ret) {
    83                 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
    84                                                             ret, cred);
    85                 DEBUG(1,("failed to get principal from ccache: %s\n",
    86                          err_mess));
    87                 talloc_free(err_mess);
     91                (*error_string) = talloc_asprintf(cred, "failed to get principal from ccache: %s\n",
     92                                                  smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
     93                                                                             ret, cred));
    8894                return ret;
    8995        }
     
    9197        ret = krb5_unparse_name(ccache->smb_krb5_context->krb5_context, princ, &name);
    9298        if (ret) {
    93                 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, ret, cred);
    94                 DEBUG(1,("failed to unparse principal from ccache: %s\n",
    95                          err_mess));
    96                 talloc_free(err_mess);
     99                (*error_string) = talloc_asprintf(cred, "failed to unparse principal from ccache: %s\n",
     100                                                  smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context,
     101                                                                             ret, cred));
    97102                return ret;
    98103        }
     
    126131
    127132_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred,
    128                                         struct tevent_context *event_ctx,
    129                                struct loadparm_context *lp_ctx,
    130                                const char *name,
    131                                enum credentials_obtained obtained)
     133                                        struct loadparm_context *lp_ctx,
     134                                        const char *name,
     135                                        enum credentials_obtained obtained,
     136                                        const char **error_string)
    132137{
    133138        krb5_error_code ret;
     
    140145        ccc = talloc(cred, struct ccache_container);
    141146        if (!ccc) {
    142                 return ENOMEM;
    143         }
    144 
    145         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
     147                (*error_string) = error_message(ENOMEM);
     148                return ENOMEM;
     149        }
     150
     151        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
    146152                                               &ccc->smb_krb5_context);
    147153        if (ret) {
     154                (*error_string) = error_message(ret);
    148155                talloc_free(ccc);
    149156                return ret;
     
    151158        if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
    152159                talloc_free(ccc);
     160                (*error_string) = error_message(ENOMEM);
    153161                return ENOMEM;
    154162        }
     
    157165                ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
    158166                if (ret) {
    159                         DEBUG(1,("failed to read krb5 ccache: %s: %s\n",
    160                                  name,
    161                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     167                        (*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n",
     168                                                          name,
     169                                                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     170                                                                                     ret, ccc));
    162171                        talloc_free(ccc);
    163172                        return ret;
     
    166175                ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);
    167176                if (ret) {
    168                         DEBUG(3,("failed to read default krb5 ccache: %s\n",
    169                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     177                        (*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n",
     178                                                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     179                                                                                     ret, ccc));
    170180                        talloc_free(ccc);
    171181                        return ret;
     
    177187        ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);
    178188
    179         if (ret) {
    180                 DEBUG(3,("failed to get principal from default ccache: %s\n",
    181                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
    182                 talloc_free(ccc);               
    183                 return ret;
    184         }
    185 
    186         krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
    187 
    188         ret = cli_credentials_set_from_ccache(cred, ccc, obtained);
    189 
    190         if (ret) {
    191                 return ret;
    192         }
    193 
    194         cred->ccache = ccc;
    195         cred->ccache_obtained = obtained;
    196         talloc_steal(cred, ccc);
    197 
    198         cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
     189        if (ret == 0) {
     190                krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
     191                ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);
     192
     193                if (ret) {
     194                        (*error_string) = error_message(ret);
     195                        return ret;
     196                }
     197
     198                cred->ccache = ccc;
     199                cred->ccache_obtained = obtained;
     200                talloc_steal(cred, ccc);
     201
     202                cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
     203                return 0;
     204        }
    199205        return 0;
    200206}
     
    202208
    203209static int cli_credentials_new_ccache(struct cli_credentials *cred,
    204                                       struct tevent_context *event_ctx,
    205210                                      struct loadparm_context *lp_ctx,
    206                                       struct ccache_container **_ccc)
    207 {
     211                                      char *ccache_name,
     212                                      struct ccache_container **_ccc,
     213                                      const char **error_string)
     214{
     215        bool must_free_cc_name = false;
    208216        krb5_error_code ret;
    209217        struct ccache_container *ccc = talloc(cred, struct ccache_container);
    210         char *ccache_name;
    211218        if (!ccc) {
    212219                return ENOMEM;
    213220        }
    214221
    215         ccache_name = talloc_asprintf(ccc, "MEMORY:%p",
    216                                       ccc);
    217 
    218         if (!ccache_name) {
     222        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
     223                                               &ccc->smb_krb5_context);
     224        if (ret) {
    219225                talloc_free(ccc);
    220                 return ENOMEM;
    221         }
    222 
    223         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
    224                                                &ccc->smb_krb5_context);
    225         if (ret) {
    226                 talloc_free(ccc);
     226                (*error_string) = talloc_asprintf(cred, "Failed to get krb5_context: %s",
     227                                                  error_message(ret));
    227228                return ret;
    228229        }
    229230        if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
    230231                talloc_free(ccc);
    231                 return ENOMEM;
     232                (*error_string) = strerror(ENOMEM);
     233                return ENOMEM;
     234        }
     235
     236        if (!ccache_name) {
     237                must_free_cc_name = true;
     238                ccache_name = talloc_asprintf(ccc, "MEMORY:%p",
     239                                              ccc);
     240               
     241                if (!ccache_name) {
     242                        talloc_free(ccc);
     243                        (*error_string) = strerror(ENOMEM);
     244                        return ENOMEM;
     245                }
    232246        }
    233247
     
    235249                              &ccc->ccache);
    236250        if (ret) {
    237                 DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n",
    238                          ccache_name,
    239                          smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
     251                (*error_string) = talloc_asprintf(cred, "failed to resolve a krb5 ccache (%s): %s\n",
     252                                                  ccache_name,
     253                                                  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
     254                                                                             ret, ccc));
    240255                talloc_free(ccache_name);
    241256                talloc_free(ccc);
     
    243258        }
    244259
    245         talloc_set_destructor(ccc, free_mccache);
    246 
    247         talloc_free(ccache_name);
     260        if (strncasecmp(ccache_name, "MEMORY:", 7) == 0) {
     261                talloc_set_destructor(ccc, free_mccache);
     262        } else {
     263                talloc_set_destructor(ccc, free_dccache);
     264        }
     265
     266        if (must_free_cc_name) {
     267                talloc_free(ccache_name);
     268        }
    248269
    249270        *_ccc = ccc;
    250271
    251         return ret;
    252 }
    253 
    254 _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred,
    255                                         struct tevent_context *event_ctx,
    256                                struct loadparm_context *lp_ctx,
    257                                struct ccache_container **ccc)
     272        return 0;
     273}
     274
     275_PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred,
     276                                              struct tevent_context *event_ctx,
     277                                              struct loadparm_context *lp_ctx,
     278                                              char *ccache_name,
     279                                              struct ccache_container **ccc,
     280                                              const char **error_string)
    258281{
    259282        krb5_error_code ret;
     283        enum credentials_obtained obtained;
    260284       
    261285        if (cred->machine_account_pending) {
     
    269293        }
    270294        if (cli_credentials_is_anonymous(cred)) {
     295                (*error_string) = "Cannot get anonymous kerberos credentials";
    271296                return EINVAL;
    272297        }
    273298
    274         ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccc);
    275         if (ret) {
    276                 return ret;
    277         }
    278 
    279         ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache);
     299        ret = cli_credentials_new_ccache(cred, lp_ctx, ccache_name, ccc, error_string);
     300        if (ret) {
     301                return ret;
     302        }
     303
     304        ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string);
    280305        if (ret) {
    281306                return ret;
     
    283308
    284309        ret = cli_credentials_set_from_ccache(cred, *ccc,
    285                                               (MAX(MAX(cred->principal_obtained,
    286                                                        cred->username_obtained),
    287                                                    cred->password_obtained)));
     310                                              obtained, error_string);
    288311       
    289312        cred->ccache = *ccc;
     
    293316        }
    294317        cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
    295         return ret;
     318        return 0;
     319}
     320
     321_PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred,
     322                                        struct tevent_context *event_ctx,
     323                                        struct loadparm_context *lp_ctx,
     324                                        struct ccache_container **ccc,
     325                                        const char **error_string)
     326{
     327        return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string);
     328}
     329
     330/* We have good reason to think the ccache in these credentials is invalid - blow it away */
     331static void cli_credentials_unconditionally_invalidate_client_gss_creds(struct cli_credentials *cred)
     332{
     333        if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
     334                talloc_unlink(cred, cred->client_gss_creds);
     335                cred->client_gss_creds = NULL;
     336        }
     337        cred->client_gss_creds_obtained = CRED_UNINITIALISED;
    296338}
    297339
     
    317359}
    318360
     361/* We have good reason to think this CCACHE is invalid.  Blow it away */
     362static void cli_credentials_unconditionally_invalidate_ccache(struct cli_credentials *cred)
     363{
     364        if (cred->ccache_obtained > CRED_UNINITIALISED) {
     365                talloc_unlink(cred, cred->ccache);
     366                cred->ccache = NULL;
     367        }
     368        cred->ccache_obtained = CRED_UNINITIALISED;
     369
     370        cli_credentials_unconditionally_invalidate_client_gss_creds(cred);
     371}
     372
    319373_PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred,
    320374                                       enum credentials_obtained obtained)
     
    349403
    350404_PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
    351                                          struct tevent_context *event_ctx,
    352                                          struct loadparm_context *lp_ctx,
    353                                          struct gssapi_creds_container **_gcc)
     405                                                  struct tevent_context *event_ctx,
     406                                                  struct loadparm_context *lp_ctx,
     407                                                  struct gssapi_creds_container **_gcc,
     408                                                  const char **error_string)
    354409{
    355410        int ret = 0;
     
    366421        }
    367422
    368         ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, 
    369                                          &ccache);
     423        ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
     424                                         &ccache, error_string);
    370425        if (ret) {
    371426                DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret)));
     
    375430        gcc = talloc(cred, struct gssapi_creds_container);
    376431        if (!gcc) {
     432                (*error_string) = error_message(ENOMEM);
    377433                return ENOMEM;
    378434        }
     
    380436        maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
    381437                                        &gcc->creds);
     438        if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) {
     439                /* This CCACHE is no good.  Ensure we don't use it again */
     440                cli_credentials_unconditionally_invalidate_ccache(cred);
     441
     442                /* Now try again to get a ccache */
     443                ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
     444                                                 &ccache, error_string);
     445                if (ret) {
     446                        DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret)));
     447                        return ret;
     448                }
     449
     450                maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
     451                                                &gcc->creds);
     452
     453        }
     454
    382455        if (maj_stat) {
    383456                talloc_free(gcc);
     
    387460                        ret = EINVAL;
    388461                }
     462                (*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret));
    389463                return ret;
    390464        }
     
    409483
    410484                maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds,
    411                                                            num_ktypes, etypes);
     485                                                           num_ktypes,
     486                                                           (int32_t *) etypes);
    412487                krb5_xfree (etypes);
    413488                if (maj_stat) {
     
    418493                                ret = EINVAL;
    419494                        }
     495                        (*error_string) = talloc_asprintf(cred, "gss_krb5_set_allowable_enctypes failed: %s", error_message(ret));
    420496                        return ret;
    421497                }
     
    433509                        ret = EINVAL;
    434510                }
     511                (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret));
    435512                return ret;
    436513        }
     
    455532
    456533 int cli_credentials_set_client_gss_creds(struct cli_credentials *cred,
    457                                           struct tevent_context *event_ctx,
    458534                                          struct loadparm_context *lp_ctx,
    459535                                          gss_cred_id_t gssapi_cred,
    460                                           enum credentials_obtained obtained)
     536                                          enum credentials_obtained obtained,
     537                                          const char **error_string)
    461538{
    462539        int ret;
     
    470547        gcc = talloc(cred, struct gssapi_creds_container);
    471548        if (!gcc) {
    472                 return ENOMEM;
    473         }
    474 
    475         ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, &ccc);
     549                (*error_string) = error_message(ENOMEM);
     550                return ENOMEM;
     551        }
     552
     553        ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string);
    476554        if (ret != 0) {
    477555                return ret;
     
    486564                        ret = EINVAL;
    487565                }
     566                if (ret) {
     567                        (*error_string) = error_message(ENOMEM);
     568                }
    488569        }
    489570
    490571        if (ret == 0) {
    491                 ret = cli_credentials_set_from_ccache(cred, ccc, obtained);
     572                ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);
    492573        }
    493574        cred->ccache = ccc;
     
    510591 */
    511592_PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
    512                                         struct tevent_context *event_ctx,
    513                                struct loadparm_context *lp_ctx,
    514                                struct keytab_container **_ktc)
     593                                        struct loadparm_context *lp_ctx,
     594                                        struct keytab_container **_ktc)
    515595{
    516596        krb5_error_code ret;
    517597        struct keytab_container *ktc;
    518598        struct smb_krb5_context *smb_krb5_context;
    519         const char **enctype_strings;
    520599        TALLOC_CTX *mem_ctx;
    521600
     
    530609        }
    531610
    532         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,
     611        ret = cli_credentials_get_krb5_context(cred, lp_ctx,
    533612                                               &smb_krb5_context);
    534613        if (ret) {
     
    541620        }
    542621
    543         enctype_strings = cli_credentials_get_enctype_strings(cred);
    544        
    545622        ret = smb_krb5_create_memory_keytab(mem_ctx, cred,
    546                                             smb_krb5_context,
    547                                             enctype_strings, &ktc);
     623                                            smb_krb5_context, &ktc);
    548624        if (ret) {
    549625                talloc_free(mem_ctx);
     
    565641
    566642_PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
    567                                              struct tevent_context *event_ctx,
    568                                     struct loadparm_context *lp_ctx,
    569                                     const char *keytab_name,
    570                                     enum credentials_obtained obtained)
     643                                             struct loadparm_context *lp_ctx,
     644                                             const char *keytab_name,
     645                                             enum credentials_obtained obtained)
    571646{
    572647        krb5_error_code ret;
     
    579654        }
    580655
    581         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
     656        ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
    582657        if (ret) {
    583658                return ret;
     
    604679}
    605680
    606 _PUBLIC_ int cli_credentials_update_keytab(struct cli_credentials *cred,
    607                                            struct tevent_context *event_ctx,
    608                                   struct loadparm_context *lp_ctx)
    609 {
    610         krb5_error_code ret;
    611         struct keytab_container *ktc;
    612         struct smb_krb5_context *smb_krb5_context;
    613         const char **enctype_strings;
    614         TALLOC_CTX *mem_ctx;
    615        
    616         mem_ctx = talloc_new(cred);
    617         if (!mem_ctx) {
    618                 return ENOMEM;
    619         }
    620 
    621         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
    622         if (ret) {
    623                 talloc_free(mem_ctx);
    624                 return ret;
    625         }
    626 
    627         enctype_strings = cli_credentials_get_enctype_strings(cred);
    628        
    629         ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);
    630         if (ret != 0) {
    631                 talloc_free(mem_ctx);
    632                 return ret;
    633         }
    634 
    635         ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, ktc);
    636 
    637         talloc_free(mem_ctx);
    638         return ret;
    639 }
    640 
    641681/* Get server gss credentials (in gsskrb5, this means the keytab) */
    642682
    643683_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred,
    644                                                   struct tevent_context *event_ctx,
    645                                          struct loadparm_context *lp_ctx,
    646                                          struct gssapi_creds_container **_gcc)
     684                                                  struct loadparm_context *lp_ctx,
     685                                                  struct gssapi_creds_container **_gcc)
    647686{
    648687        int ret = 0;
     
    653692        TALLOC_CTX *mem_ctx;
    654693        krb5_principal princ;
    655 
    656         if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained,
    657                                                     MAX(cred->principal_obtained,
    658                                                         cred->username_obtained)))) {
    659                 *_gcc = cred->server_gss_creds;
    660                 return 0;
    661         }
    662 
    663         ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);
    664         if (ret) {
    665                 return ret;
    666         }
    667 
    668         ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);
    669         if (ret) {
    670                 DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
    671                 return ret;
    672         }
     694        const char *error_string;
     695        enum credentials_obtained obtained;
    673696
    674697        mem_ctx = talloc_new(cred);
     
    677700        }
    678701
    679         ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ);
    680         if (ret) {
    681                 DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n",
    682                          smb_get_krb5_error_message(smb_krb5_context->krb5_context,
    683                                                     ret, mem_ctx)));
     702        ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
     703        if (ret) {
     704                return ret;
     705        }
     706
     707        ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string);
     708        if (ret) {
     709                DEBUG(1,("cli_credentials_get_server_gss_creds: making krb5 principal failed (%s)\n",
     710                         error_string));
    684711                talloc_free(mem_ctx);
     712                return ret;
     713        }
     714
     715        if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) {
     716                talloc_free(mem_ctx);
     717                *_gcc = cred->server_gss_creds;
     718                return 0;
     719        }
     720
     721        ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc);
     722        if (ret) {
     723                DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
    685724                return ret;
    686725        }
     
    732771
    733772
    734 const char **cli_credentials_get_enctype_strings(struct cli_credentials *cred)
    735 {
    736         /* If this is ever made user-configurable, we need to add code
    737          * to remove/hide the other entries from the generated
    738          * keytab */
    739         static const char *default_enctypes[] = {
    740                 "des-cbc-md5",
    741                 "aes256-cts-hmac-sha1-96",
    742                 "des3-cbc-sha1",
    743                 "arcfour-hmac-md5",
    744                 NULL
    745         };
    746         return default_enctypes;
    747 }
    748 
    749773const char *cli_credentials_get_salt_principal(struct cli_credentials *cred)
    750774{
     
    754778_PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal)
    755779{
     780        talloc_free(cred->salt_principal);
    756781        cred->salt_principal = talloc_strdup(cred, principal);
    757782}
    758783
    759 
     784/* The 'impersonate_principal' is used to allow on Kerberos principal
     785 * (and it's associated keytab etc) to impersonate another.  The
     786 * ability to do this is controlled by the KDC, but it is generally
     787 * permitted to impersonate anyone to yourself.  This allows any
     788 * member of the domain to get the groups of a user.  This is also
     789 * known as S4U2Self */
     790
     791const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred)
     792{
     793        return cred->impersonate_principal;
     794}
     795
     796_PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal)
     797{
     798        talloc_free(cred->impersonate_principal);
     799        cred->impersonate_principal = talloc_strdup(cred, principal);
     800}
     801
     802/* when impersonating for S4U2Self we need to set the target principal
     803 * to ourself, as otherwise we would need additional rights.
     804 * Similarly, we may only be authorized to do general impersonation to
     805 * some particular services.
     806 *
     807 * Likewise, password changes typically require a ticket to kpasswd/realm directly, not via a TGT
     808 *
     809 * NULL means that tickets will be obtained for the krbtgt service.
     810*/
     811
     812const char *cli_credentials_get_target_service(struct cli_credentials *cred)
     813{
     814        return cred->target_service;
     815}
     816
     817_PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, const char *target_service)
     818{
     819        talloc_free(cred->target_service);
     820        cred->target_service = talloc_strdup(cred, target_service);
     821}
     822
  • 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       
     54void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred,
     55                                                 enum credentials_obtained obtained);
     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#include <Python.h>
    1920#include "includes.h"
    20 #include <Python.h>
    2121#include "pycredentials.h"
    2222#include "param/param.h"
     
    2525#include "libcli/util/pyerrors.h"
    2626#include "param/pyparam.h"
    27 
    28 #ifndef Py_RETURN_NONE
    29 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    30 #endif
     27#include <tevent.h>
    3128
    3229static PyObject *PyString_FromStringOrNULL(const char *str)
     
    197194}
    198195
     196static PyObject *py_creds_set_krb_forwardable(py_talloc_Object *self, PyObject *args)
     197{
     198        int state;
     199        if (!PyArg_ParseTuple(args, "i", &state))
     200                return NULL;
     201
     202        cli_credentials_set_krb_forwardable(PyCredentials_AsCliCredentials(self), state);
     203        Py_RETURN_NONE;
     204}
     205
    199206static PyObject *py_creds_guess(py_talloc_Object *self, PyObject *args)
    200207{
    201208        PyObject *py_lp_ctx = Py_None;
    202209        struct loadparm_context *lp_ctx;
     210        TALLOC_CTX *mem_ctx;
     211        struct cli_credentials *creds;
     212
     213        creds = PyCredentials_AsCliCredentials(self);
     214
    203215        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    204216                return NULL;
    205217
    206         lp_ctx = lp_from_py_object(py_lp_ctx);
    207         if (lp_ctx == NULL)
    208                 return NULL;
    209 
    210         cli_credentials_guess(PyCredentials_AsCliCredentials(self), lp_ctx);
     218        mem_ctx = talloc_new(NULL);
     219        if (mem_ctx == NULL) {
     220                PyErr_NoMemory();
     221                return NULL;
     222        }
     223
     224        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     225        if (lp_ctx == NULL) {
     226                talloc_free(mem_ctx);
     227                return NULL;
     228        }
     229
     230        cli_credentials_guess(creds, lp_ctx);
     231
     232        talloc_free(mem_ctx);
    211233
    212234        Py_RETURN_NONE;
     
    218240        struct loadparm_context *lp_ctx;
    219241        NTSTATUS status;
     242        struct cli_credentials *creds;
     243        TALLOC_CTX *mem_ctx;
     244
     245        creds = PyCredentials_AsCliCredentials(self);
     246
    220247        if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))
    221248                return NULL;
    222249
    223         lp_ctx = lp_from_py_object(py_lp_ctx);
    224         if (lp_ctx == NULL)
    225                 return NULL;
    226 
    227         status = cli_credentials_set_machine_account(PyCredentials_AsCliCredentials(self), lp_ctx);
     250        mem_ctx = talloc_new(NULL);
     251        if (mem_ctx == NULL) {
     252                PyErr_NoMemory();
     253                return NULL;
     254        }
     255
     256        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     257        if (lp_ctx == NULL) {
     258                talloc_free(mem_ctx);
     259                return NULL;
     260        }
     261
     262        status = cli_credentials_set_machine_account(creds, lp_ctx);
     263        talloc_free(mem_ctx);
     264
    228265        PyErr_NTSTATUS_IS_ERR_RAISE(status);
    229266
    230267        Py_RETURN_NONE;
    231268}
     269
     270PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc)
     271{
     272        PyCredentialCacheContainerObject *py_ret;
     273
     274        if (ccc == NULL) {
     275                Py_RETURN_NONE;
     276        }
     277
     278        py_ret = (PyCredentialCacheContainerObject *)PyCredentialCacheContainer.tp_alloc(&PyCredentialCacheContainer, 0);
     279        if (py_ret == NULL) {
     280                PyErr_NoMemory();
     281                return NULL;
     282        }
     283        py_ret->mem_ctx = talloc_new(NULL);
     284        py_ret->ccc = talloc_reference(py_ret->mem_ctx, ccc);
     285        return (PyObject *)py_ret;
     286}
     287
     288
     289static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *args)
     290{
     291        PyObject *py_lp_ctx = Py_None;
     292        char *ccache_name;
     293        struct loadparm_context *lp_ctx;
     294        struct ccache_container *ccc;
     295        struct tevent_context *event_ctx;
     296        int ret;
     297        const char *error_string;
     298        struct cli_credentials *creds;
     299        TALLOC_CTX *mem_ctx;
     300
     301        creds = PyCredentials_AsCliCredentials(self);
     302
     303        if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name))
     304                return NULL;
     305
     306        mem_ctx = talloc_new(NULL);
     307        if (mem_ctx == NULL) {
     308                PyErr_NoMemory();
     309                return NULL;
     310        }
     311
     312        lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
     313        if (lp_ctx == NULL) {
     314                talloc_free(mem_ctx);
     315                return NULL;
     316        }
     317
     318        event_ctx = tevent_context_init(mem_ctx);
     319
     320        ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx,
     321                                               ccache_name, &ccc, &error_string);
     322        talloc_unlink(mem_ctx, lp_ctx);
     323        if (ret == 0) {
     324                talloc_steal(ccc, event_ctx);
     325                talloc_free(mem_ctx);
     326                return PyCredentialCacheContainer_from_ccache_container(ccc);
     327        }
     328
     329        PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL");
     330
     331        talloc_free(mem_ctx);
     332        return NULL;
     333}
     334
     335static PyObject *py_creds_set_gensec_features(py_talloc_Object *self, PyObject *args)
     336{
     337        unsigned int gensec_features;
     338
     339        if (!PyArg_ParseTuple(args, "I", &gensec_features))
     340                return NULL;
     341
     342        cli_credentials_set_gensec_features(PyCredentials_AsCliCredentials(self), gensec_features);
     343
     344        Py_RETURN_NONE;
     345}
     346
     347static PyObject *py_creds_get_gensec_features(py_talloc_Object *self, PyObject *args)
     348{
     349        unsigned int gensec_features;
     350
     351        gensec_features = cli_credentials_get_gensec_features(PyCredentials_AsCliCredentials(self));
     352        return PyInt_FromLong(gensec_features);
     353}
     354
    232355
    233356static PyMethodDef py_creds_methods[] = {
     
    285408        { "set_kerberos_state", (PyCFunction)py_creds_set_kerberos_state, METH_VARARGS,
    286409                NULL },
     410        { "set_krb_forwardable", (PyCFunction)py_creds_set_krb_forwardable, METH_VARARGS,
     411                NULL },
    287412        { "guess", (PyCFunction)py_creds_guess, METH_VARARGS, NULL },
    288413        { "set_machine_account", (PyCFunction)py_creds_set_machine_account, METH_VARARGS, NULL },
     414        { "get_named_ccache", (PyCFunction)py_creds_get_named_ccache, METH_VARARGS, NULL },
     415        { "set_gensec_features", (PyCFunction)py_creds_set_gensec_features, METH_VARARGS, NULL },
     416        { "get_gensec_features", (PyCFunction)py_creds_get_gensec_features, METH_NOARGS, NULL },
    289417        { NULL }
    290418};
     
    293421        .tp_name = "Credentials",
    294422        .tp_basicsize = sizeof(py_talloc_Object),
    295         .tp_dealloc = py_talloc_dealloc,
    296423        .tp_new = py_creds_new,
    297424        .tp_flags = Py_TPFLAGS_DEFAULT,
     
    299426};
    300427
     428
     429PyTypeObject PyCredentialCacheContainer = {
     430        .tp_name = "CredentialCacheContainer",
     431        .tp_basicsize = sizeof(py_talloc_Object),
     432        .tp_flags = Py_TPFLAGS_DEFAULT,
     433};
     434
    301435void initcredentials(void)
    302436{
    303437        PyObject *m;
     438        PyTypeObject *talloc_type = PyTalloc_GetObjectType();
     439        if (talloc_type == NULL)
     440                return;
     441
     442        PyCredentials.tp_base = PyCredentialCacheContainer.tp_base = talloc_type;
    304443
    305444        if (PyType_Ready(&PyCredentials) < 0)
     445                return;
     446
     447        if (PyType_Ready(&PyCredentialCacheContainer) < 0)
    306448                return;
    307449
     
    314456        PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS));
    315457
     458        PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE",  PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE));
     459        PyModule_AddObject(m, "NO_KRB_FORWARDABLE",    PyInt_FromLong(CRED_NO_KRB_FORWARDABLE));
     460        PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE));
     461
    316462        Py_INCREF(&PyCredentials);
    317463        PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
    318 }
     464        Py_INCREF(&PyCredentialCacheContainer);
     465        PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer);
     466}
  • trunk/server/source4/auth/credentials/pycredentials.h

    r414 r745  
    2121
    2222#include "auth/credentials/credentials.h"
    23 #include "pytalloc.h"
     23#include <pytalloc.h>
    2424
    25 PyAPI_DATA(PyTypeObject) PyCredentials;
     25extern PyTypeObject PyCredentials;
     26extern PyTypeObject PyCredentialCacheContainer;
     27typedef struct {
     28        PyObject_HEAD
     29        TALLOC_CTX *mem_ctx;
     30        struct ccache_container *ccc;
     31} PyCredentialCacheContainerObject;
    2632#define PyCredentials_Check(py_obj) PyObject_TypeCheck(py_obj, &PyCredentials)
    2733#define PyCredentials_AsCliCredentials(py_obj) py_talloc_get_type(py_obj, struct cli_credentials)
  • 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);
Note: See TracChangeset for help on using the changeset viewer.