#include "librpc/gen_ndr/samr.h" /* for struct samrPassword */
#include "auth/credentials/credentials.h"
#include "auth/credentials/credentials_internal.h"
+#include "auth/gensec/gensec.h"
#include "libcli/auth/libcli_auth.h"
#include "tevent.h"
#include "param/param.h"
* @retval The username set on this context.
* @note Return value will never be NULL except by programmer error.
*/
-_PUBLIC_ const char *cli_credentials_get_principal_and_obtained(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, enum credentials_obtained *obtained)
+_PUBLIC_ char *cli_credentials_get_principal_and_obtained(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, enum credentials_obtained *obtained)
{
if (cred->machine_account_pending) {
cli_credentials_set_machine_account(cred,
* @retval The username set on this context.
* @note Return value will never be NULL except by programmer error.
*/
-_PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
+_PUBLIC_ char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
{
enum credentials_obtained obtained;
return cli_credentials_get_principal_and_obtained(cred, mem_ctx, &obtained);
enum credentials_obtained obtained)
{
if (obtained >= cred->principal_obtained) {
+ struct loadparm_context *lp_ctx;
+ bool ok;
+
cred->principal = talloc_strdup(cred, val);
+ if (cred->principal == NULL) {
+ return false;
+ }
cred->principal_obtained = obtained;
+
cli_credentials_invalidate_ccache(cred, cred->principal_obtained);
- return true;
+
+ lp_ctx = loadparm_init_s3(cred, loadparm_s3_helpers());
+ if (lp_ctx == NULL) {
+ return false;
+ }
+ ok = cli_credentials_ccache_reinit(cred, lp_ctx);
+ talloc_free(lp_ctx);
+
+ return ok;
}
return false;
_PUBLIC_ bool cli_credentials_authentication_requested(struct cli_credentials *cred)
{
+ uint32_t gensec_features = 0;
+
if (cred->bind_dn) {
return true;
}
return true;
}
+ gensec_features = cli_credentials_get_gensec_features(cred);
+ if (gensec_features & GENSEC_FEATURE_NTLM_CCACHE) {
+ return true;
+ }
+
+ if (gensec_features & GENSEC_FEATURE_SIGN) {
+ return true;
+ }
+
+ if (gensec_features & GENSEC_FEATURE_SEAL) {
+ return true;
+ }
+
return false;
}
password, password_len);
if (converted != sizeof(nt_hash->hash)) {
TALLOC_FREE(nt_hash);
- return false;
+ return NULL;
}
} else {
E_md4hash(password, nt_hash->hash);
/**
* Set the realm for this credentials context, and force it to
- * uppercase for the sainity of our local kerberos libraries
+ * uppercase for the sanity of our local kerberos libraries
*/
_PUBLIC_ bool cli_credentials_set_realm(struct cli_credentials *cred,
const char *val,
uname = talloc_strdup(credentials, data);
if ((p = strchr_m(uname,'%'))) {
- *p = 0;
- cli_credentials_set_password(credentials, p+1, obtained);
+ const char *password;
+
+ *p = '\0';
+ password = p + 1;
+ if (password[0] != '\0') {
+ cli_credentials_set_password(credentials,
+ password,
+ obtained);
+ }
}
if ((p = strchr_m(uname,'@'))) {
- /*
- * We also need to set username and domain
- * in order to undo the effect of
- * cli_credentials_guess().
- */
- cli_credentials_set_username(credentials, uname, obtained);
- cli_credentials_set_domain(credentials, "", obtained);
+ const char *realm = p + 1;
- cli_credentials_set_principal(credentials, uname, obtained);
- *p = 0;
- cli_credentials_set_realm(credentials, p+1, obtained);
+ if (realm[0] == '\0') {
+ *p = 0;
+
+ /*
+ * We also need to set username and domain
+ * in order to undo the effect of
+ * cli_credentials_guess().
+ */
+ cli_credentials_set_username(credentials,
+ uname,
+ obtained);
+ cli_credentials_set_domain(credentials, "", obtained);
+ } else {
+ cli_credentials_set_principal(credentials,
+ uname,
+ obtained);
+ *p = 0;
+
+ cli_credentials_set_realm(credentials, realm, obtained);
+ }
return;
} else if ((p = strchr_m(uname,'\\'))
|| (p = strchr_m(uname, '/'))
* @param mem_ctx The memory context to place the result on
*/
-_PUBLIC_ const char *cli_credentials_get_unparsed_name(struct cli_credentials *credentials, TALLOC_CTX *mem_ctx)
+_PUBLIC_ char *cli_credentials_get_unparsed_name(struct cli_credentials *credentials, TALLOC_CTX *mem_ctx)
{
const char *bind_dn = cli_credentials_get_bind_dn(credentials);
- const char *domain;
- const char *username;
- const char *name;
+ const char *domain = NULL;
+ const char *username = NULL;
+ char *name = NULL;
if (bind_dn) {
name = talloc_strdup(mem_ctx, bind_dn);
* Attach NETLOGON credentials for use with SCHANNEL
*/
-_PUBLIC_ void cli_credentials_set_netlogon_creds(struct cli_credentials *cred,
- struct netlogon_creds_CredentialState *netlogon_creds)
+_PUBLIC_ void cli_credentials_set_netlogon_creds(
+ struct cli_credentials *cred,
+ const struct netlogon_creds_CredentialState *netlogon_creds)
{
TALLOC_FREE(cred->netlogon_creds);
if (netlogon_creds == NULL) {
*++p = '\0'; /* advance p, and null-terminate pass */
break;
}
- /* fall through */
+
+ FALL_THROUGH;
case 0:
if (p - pass) {
*p = '\0'; /* null-terminate it, just in case... */
p = NULL; /* then force the loop condition to become false */
break;
- } else {
- fprintf(stderr, "Error reading password from file descriptor %d: %s\n", fd, "empty password\n");
- return false;
}
+ fprintf(stderr,
+ "Error reading password from file descriptor "
+ "%d: empty password\n",
+ fd);
+ return false;
+
default:
fprintf(stderr, "Error reading password from file descriptor %d: %s\n",
fd, strerror(errno));
}
+/**
+ * Encrypt a data blob using the session key and the negotiated encryption
+ * algorithm
+ *
+ * @param state Credential state, contains the session key and algorithm
+ * @param data Data blob containing the data to be encrypted.
+ *
+ */
+_PUBLIC_ NTSTATUS netlogon_creds_session_encrypt(
+ struct netlogon_creds_CredentialState *state,
+ DATA_BLOB data)
+{
+ if (data.data == NULL || data.length == 0) {
+ DBG_ERR("Nothing to encrypt "
+ "data.data == NULL or data.length == 0");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ /*
+ * Don't crypt an all-zero password it will give away the
+ * NETLOGON pipe session key .
+ */
+ if (all_zero(data.data, data.length)) {
+ DBG_ERR("Supplied data all zeros, could leak session key");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ if (state->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
+ netlogon_creds_aes_encrypt(state,
+ data.data,
+ data.length);
+ } else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
+ netlogon_creds_arcfour_crypt(state,
+ data.data,
+ data.length);
+ } else {
+ DBG_ERR("Unsupported encryption option negotiated");
+ return NT_STATUS_NOT_SUPPORTED;
+ }
+ return NT_STATUS_OK;
+}
+