diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 14ee78202a..991029d203 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2185,6 +2185,204 @@ static int rpc_pipe_destructor(struct rpc_pipe_client *p) return ret ? -1 : 0; } +NTSTATUS rpccli_anon_bind_data(TALLOC_CTX *mem_ctx, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_NONE; + result->auth_level = PIPE_AUTH_LEVEL_NONE; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); + if ((result->user_name == NULL) || (result->domain == NULL)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + *presult = result; + return NT_STATUS_OK; +} + +static int cli_auth_ntlmssp_data_destructor(struct cli_pipe_auth_data *auth) +{ + ntlmssp_end(&auth->a_u.ntlmssp_state); + return 0; +} + +NTSTATUS rpccli_ntlmssp_bind_data(TALLOC_CTX *mem_ctx, + enum pipe_auth_type auth_type, + enum pipe_auth_level auth_level, + const char *domain, + const char *username, + const char *password, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + NTSTATUS status; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = auth_type; + result->auth_level = auth_level; + + result->user_name = talloc_strdup(result, username); + result->domain = talloc_strdup(result, domain); + if ((result->user_name == NULL) || (result->domain == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + status = ntlmssp_client_start(&result->a_u.ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + talloc_set_destructor(result, cli_auth_ntlmssp_data_destructor); + + status = ntlmssp_set_username(result->a_u.ntlmssp_state, username); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + status = ntlmssp_set_domain(result->a_u.ntlmssp_state, domain); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + status = ntlmssp_set_password(result->a_u.ntlmssp_state, password); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + /* + * Turn off sign+seal to allow selected auth level to turn it back on. + */ + result->a_u.ntlmssp_state->neg_flags &= + ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL); + + if (auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + result->a_u.ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } else if (auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + result->a_u.ntlmssp_state->neg_flags + |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_SIGN; + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return status; +} + +NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, + enum pipe_auth_level auth_level, + const struct dcinfo *pdc, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_SCHANNEL; + result->auth_level = auth_level; + + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, domain); + if ((result->user_name == NULL) || (result->domain == NULL)) { + goto fail; + } + + result->a_u.schannel_auth = talloc(result, + struct schannel_auth_struct); + if (result->a_u.schannel_auth == NULL) { + goto fail; + } + + memcpy(result->a_u.schannel_auth->sess_key, pdc->sess_key, 16); + result->a_u.schannel_auth->seq_num = 0; + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; +} + +static int cli_auth_kerberos_data_destructor(struct kerberos_auth_struct *auth) +{ + data_blob_free(&auth->session_key); + return 0; +} + +NTSTATUS rpccli_krb5_bind_data(TALLOC_CTX *mem_ctx, + enum pipe_auth_level auth_level, + const char *service_princ, + const char *username, + const char *password, + struct cli_pipe_auth_data **presult) +{ + struct cli_pipe_auth_data *result; + + if ((username != NULL) && (password != NULL)) { + int ret = kerberos_kinit_password(username, password, 0, NULL); + if (ret != 0) { + return NT_STATUS_ACCESS_DENIED; + } + } + + result = talloc(mem_ctx, struct cli_pipe_auth_data); + if (result == NULL) { + return NT_STATUS_NO_MEMORY; + } + + result->auth_type = PIPE_AUTH_TYPE_KRB5; + result->auth_level = auth_level; + + /* + * Username / domain need fixing! + */ + result->user_name = talloc_strdup(result, ""); + result->domain = talloc_strdup(result, ""); + if ((result->user_name == NULL) || (result->domain == NULL)) { + goto fail; + } + + result->a_u.kerberos_auth = TALLOC_ZERO_P( + result, struct kerberos_auth_struct); + if (result->a_u.kerberos_auth == NULL) { + goto fail; + } + talloc_set_destructor(result->a_u.kerberos_auth, + cli_auth_kerberos_data_destructor); + + result->a_u.kerberos_auth->service_principal = talloc_strdup( + result, service_princ); + if (result->a_u.kerberos_auth->service_principal == NULL) { + goto fail; + } + + *presult = result; + return NT_STATUS_OK; + + fail: + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; +} + /**************************************************************************** Open a named pipe over SMB to a remote server. * |