📄 credentials_krb5.c
字号:
{ int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct ccache_container *ccache; if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && cred->client_gss_creds_obtained > CRED_UNINITIALISED) { *_gcc = cred->client_gss_creds; return 0; } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache); if (ret) { DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { return ENOMEM; } maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, &gcc->creds); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { cred->client_gss_creds_obtained = cred->ccache_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->client_gss_creds = gcc; *_gcc = gcc; } return ret;}/** Set a gssapi cred_id_t into the credentials system. (Client case) This grabs the credentials both 'intact' and getting the krb5 ccache out of it. This routine can be generalised in future for the case where we deal with GSSAPI mechs other than krb5. On sucess, the caller must not free gssapi_cred, as it now belongs to the credentials system.*/ int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, struct event_context *event_ctx, struct loadparm_context *lp_ctx, gss_cred_id_t gssapi_cred, enum credentials_obtained obtained) { int ret; OM_uint32 maj_stat, min_stat; struct ccache_container *ccc; struct gssapi_creds_container *gcc; if (cred->client_gss_creds_obtained > obtained) { return 0; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { return ENOMEM; } ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, &ccc); if (ret != 0) { return ret; } maj_stat = gss_krb5_copy_ccache(&min_stat, gssapi_cred, ccc->ccache); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { ret = cli_credentials_set_from_ccache(cred, ccc, obtained); } cred->ccache = ccc; cred->ccache_obtained = obtained; if (ret == 0) { gcc->creds = gssapi_cred; talloc_set_destructor(gcc, free_gssapi_creds); /* set the clinet_gss_creds_obtained here, as it just got set to UNINITIALISED by the calls above */ cred->client_gss_creds_obtained = obtained; cred->client_gss_creds = gcc; } return ret;}/* Get the keytab (actually, a container containing the krb5_keytab) * attached to this context. If this hasn't been done or set before, * it will be generated from the password. */_PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct keytab_container **_ktc){ krb5_error_code ret; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; const char **enctype_strings; TALLOC_CTX *mem_ctx; if (cred->keytab_obtained >= (MAX(cred->principal_obtained, cred->username_obtained))) { *_ktc = cred->keytab; return 0; } if (cli_credentials_is_anonymous(cred)) { return EINVAL; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); if (ret) { return ret; } mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } enctype_strings = cli_credentials_get_enctype_strings(cred); ret = smb_krb5_create_memory_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, &ktc); if (ret) { talloc_free(mem_ctx); return ret; } cred->keytab_obtained = (MAX(cred->principal_obtained, cred->username_obtained)); talloc_steal(cred, ktc); cred->keytab = ktc; *_ktc = cred->keytab; talloc_free(mem_ctx); return ret;}/* Given the name of a keytab (presumably in the format * FILE:/etc/krb5.keytab), open it and attach it */_PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred, struct event_context *event_ctx, struct loadparm_context *lp_ctx, const char *keytab_name, enum credentials_obtained obtained) { krb5_error_code ret; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; TALLOC_CTX *mem_ctx; if (cred->keytab_obtained >= obtained) { return 0; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); if (ret) { return ret; } mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, &ktc); if (ret) { return ret; } cred->keytab_obtained = obtained; talloc_steal(cred, ktc); cred->keytab = ktc; talloc_free(mem_ctx); return ret;}_PUBLIC_ int cli_credentials_update_keytab(struct cli_credentials *cred, struct event_context *event_ctx, struct loadparm_context *lp_ctx) { krb5_error_code ret; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; const char **enctype_strings; TALLOC_CTX *mem_ctx; mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); if (ret) { talloc_free(mem_ctx); return ret; } enctype_strings = cli_credentials_get_enctype_strings(cred); ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc); if (ret != 0) { talloc_free(mem_ctx); return ret; } ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, ktc); talloc_free(mem_ctx); return ret;}/* Get server gss credentials (in gsskrb5, this means the keytab) */_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct gssapi_creds_container **_gcc) { int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; TALLOC_CTX *mem_ctx; krb5_principal princ; if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, MAX(cred->principal_obtained, cred->username_obtained)))) { *_gcc = cred->server_gss_creds; return 0; } ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); if (ret) { return ret; } ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc); if (ret) { DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); return ret; } mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ); if (ret) { DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); talloc_free(mem_ctx); return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { talloc_free(mem_ctx); return ENOMEM; } /* This creates a GSSAPI cred_id_t with the principal and keytab set */ maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab, &gcc->creds); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { cred->server_gss_creds_obtained = cred->keytab_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->server_gss_creds = gcc; *_gcc = gcc; } talloc_free(mem_ctx); return ret;}/** * Set Kerberos KVNO */_PUBLIC_ void cli_credentials_set_kvno(struct cli_credentials *cred, int kvno){ cred->kvno = kvno;}/** * Return Kerberos KVNO */_PUBLIC_ int cli_credentials_get_kvno(struct cli_credentials *cred){ return cred->kvno;}const char **cli_credentials_get_enctype_strings(struct cli_credentials *cred) { /* If this is ever made user-configurable, we need to add code * to remove/hide the other entries from the generated * keytab */ static const char *default_enctypes[] = { "des-cbc-md5", "aes256-cts-hmac-sha1-96", "des3-cbc-sha1", "arcfour-hmac-md5", NULL }; return default_enctypes;}const char *cli_credentials_get_salt_principal(struct cli_credentials *cred) { return cred->salt_principal;}_PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal) { cred->salt_principal = talloc_strdup(cred, principal);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -