#include "secrets.h"
#include "rpc_client/init_lsa.h"
#include "rpc_client/cli_pipe.h"
-#include "krb5_env.h"
#include "../libcli/security/security.h"
#include "passdb.h"
#include "libsmb/libsmb.h"
+#include "../libcli/smb/smbXcli_base.h"
+#include "lib/param/loadparm.h"
/****************************************************************
****************************************************************/
*cp++ = '\0';
SAFE_FREE(my_ads->auth.realm);
my_ads->auth.realm = smb_xstrdup(cp);
- strupper_m(my_ads->auth.realm);
+ if (!strupper_m(my_ads->auth.realm)) {
+ ads_destroy(&my_ads);
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
}
}
if (!spn) {
return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
}
- strupper_m(spn);
+ if (!strupper_m(spn)) {
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
spn_array[0] = spn;
if (!name_to_fqdn(my_fqdn, r->in.machine_name)
r->out.dns_domain_name);
}
- strlower_m(my_fqdn);
+ if (!strlower_m(my_fqdn)) {
+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+ }
if (!strequal(my_fqdn, r->in.machine_name)) {
spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
NULL,
pass,
flags,
- Undefined);
+ SMB_SIGNING_DEFAULT);
}
/****************************************************************
}
if (!r->in.machine_password) {
- r->in.machine_password = generate_random_str(mem_ctx, DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ r->in.machine_password = generate_random_password(mem_ctx,
+ DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
+ DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
NT_STATUS_HAVE_NO_MEMORY(r->in.machine_password);
}
/* according to WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED */
fstrcpy(trust_passwd, r->in.admin_password);
- strlower_m(trust_passwd);
+ if (!strlower_m(trust_passwd)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
/*
* Machine names can be 15 characters, but the max length on
struct samr_Ids name_types;
union samr_UserInfo user_info;
struct dcerpc_binding_handle *b = NULL;
+ unsigned int old_timeout = 0;
+ DATA_BLOB session_key = data_blob_null;
struct samr_CryptPassword crypt_pwd;
struct samr_CryptPasswordEx crypt_pwd_ex;
}
if (!r->in.machine_password) {
- r->in.machine_password = generate_random_str(mem_ctx, DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ r->in.machine_password = generate_random_password(mem_ctx,
+ DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH,
+ DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
NT_STATUS_HAVE_NO_MEMORY(r->in.machine_password);
}
b = pipe_hnd->binding_handle;
+ status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
status = dcerpc_samr_Connect2(b, mem_ctx,
pipe_hnd->desthost,
SAMR_ACCESS_ENUM_DOMAINS
/* Create domain user */
acct_name = talloc_asprintf(mem_ctx, "%s$", r->in.machine_name);
- strlower_m(acct_name);
+ if (!strlower_m(acct_name)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
init_lsa_String(&lsa_acct_name, acct_name);
/* Set password on machine account - first try level 26 */
+ /*
+ * increase the timeout as password filter modules on the DC
+ * might delay the operation for a significant amount of time
+ */
+ old_timeout = rpccli_set_timeout(pipe_hnd, 600000);
+
init_samr_CryptPasswordEx(r->in.machine_password,
- &cli->user_session_key,
+ &session_key,
&crypt_pwd_ex);
user_info.info26.password = crypt_pwd_ex;
/* retry with level 24 */
init_samr_CryptPassword(r->in.machine_password,
- &cli->user_session_key,
+ &session_key,
&crypt_pwd);
user_info.info24.password = crypt_pwd;
&result);
}
+ old_timeout = rpccli_set_timeout(pipe_hnd, old_timeout);
+
if (!NT_STATUS_IS_OK(status)) {
dcerpc_samr_DeleteUser(b, mem_ctx,
return status;
}
+ data_blob_clear_free(&session_key);
+
if (is_valid_policy_hnd(&sam_pol)) {
dcerpc_samr_Close(b, mem_ctx, &sam_pol, &result);
}
NTSTATUS libnet_join_ok(const char *netbios_domain_name,
const char *machine_name,
- const char *dc_name)
+ const char *dc_name,
+ const bool use_kerberos)
{
uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
struct cli_state *cli = NULL;
NTSTATUS status;
char *machine_password = NULL;
char *machine_account = NULL;
+ int flags = 0;
if (!dc_name) {
return NT_STATUS_INVALID_PARAMETER;
return NT_STATUS_NO_MEMORY;
}
+ if (use_kerberos) {
+ flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+ }
+
status = cli_full_connection(&cli, NULL,
dc_name,
NULL, 0,
machine_account,
NULL,
machine_password,
- 0,
- Undefined);
+ flags,
+ SMB_SIGNING_DEFAULT);
free(machine_account);
free(machine_password);
NULL,
"",
0,
- Undefined);
+ SMB_SIGNING_DEFAULT);
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("libnet_join_ok: failed to get schannel session "
"key from server %s for domain %s. Error was %s\n",
- cli->desthost, netbios_domain_name, nt_errstr(status)));
+ smbXcli_conn_remote_name(cli->conn),
+ netbios_domain_name, nt_errstr(status)));
cli_shutdown(cli);
return status;
}
}
status = cli_rpc_pipe_open_schannel_with_key(
- cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
+ cli, &ndr_table_netlogon, NCACN_NP,
DCERPC_AUTH_LEVEL_PRIVACY,
netbios_domain_name, &netlogon_pipe->dc, &pipe_hnd);
DEBUG(0,("libnet_join_ok: failed to open schannel session "
"on netlogon pipe to server %s for domain %s. "
"Error was %s\n",
- cli->desthost, netbios_domain_name, nt_errstr(status)));
+ smbXcli_conn_remote_name(cli->conn),
+ netbios_domain_name, nt_errstr(status)));
return status;
}
status = libnet_join_ok(r->out.netbios_domain_name,
r->in.machine_name,
- r->in.dc_name);
+ r->in.dc_name,
+ r->in.use_kerberos);
if (!NT_STATUS_IS_OK(status)) {
libnet_join_set_error_string(mem_ctx, r,
"failed to verify domain membership after joining: %s",
/* Create domain user */
acct_name = talloc_asprintf(mem_ctx, "%s$", r->in.machine_name);
- strlower_m(acct_name);
+ if (!strlower_m(acct_name)) {
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto done;
+ }
init_lsa_String(&lsa_acct_name, acct_name);
return werr;
}
- lp_load(get_dyn_CONFIGFILE(),true,false,false,true);
+ lp_load_global(get_dyn_CONFIGFILE());
r->out.modified_config = true;
r->out.result = werr;
return werr;
}
- lp_load(get_dyn_CONFIGFILE(),true,false,false,true);
+ lp_load_global(get_dyn_CONFIGFILE());
r->out.modified_config = true;
r->out.result = werr;
if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
DEBUG(10,("Unable to auto-add domain administrators to "
"BUILTIN\\Administrators during join because "
- "winbindd must be running."));
+ "winbindd must be running.\n"));
} else if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("Failed to auto-add domain administrators to "
"BUILTIN\\Administrators during join: %s\n",
status = create_builtin_users(domain_sid);
if (NT_STATUS_EQUAL(status, NT_STATUS_PROTOCOL_UNREACHABLE)) {
DEBUG(10,("Unable to auto-add domain users to BUILTIN\\users "
- "during join because winbindd must be running."));
+ "during join because winbindd must be running.\n"));
} else if (!NT_STATUS_IS_OK(status)) {
DEBUG(5, ("Failed to auto-add domain administrators to "
"BUILTIN\\Administrators during join: %s\n",
static int libnet_destroy_JoinCtx(struct libnet_JoinCtx *r)
{
- const char *krb5_cc_env = NULL;
-
if (r->in.ads) {
ads_destroy(&r->in.ads);
}
- krb5_cc_env = getenv(KRB5_ENV_CCNAME);
- if (krb5_cc_env && strcasecmp_m(krb5_cc_env, "MEMORY:libnetjoin")) {
- unsetenv(KRB5_ENV_CCNAME);
- }
-
return 0;
}
static int libnet_destroy_UnjoinCtx(struct libnet_UnjoinCtx *r)
{
- const char *krb5_cc_env = NULL;
-
if (r->in.ads) {
ads_destroy(&r->in.ads);
}
- krb5_cc_env = getenv(KRB5_ENV_CCNAME);
- if (krb5_cc_env && strcasecmp_m(krb5_cc_env, "MEMORY:libnetjoin")) {
- unsetenv(KRB5_ENV_CCNAME);
- }
-
return 0;
}
struct libnet_JoinCtx **r)
{
struct libnet_JoinCtx *ctx;
- const char *krb5_cc_env = NULL;
ctx = talloc_zero(mem_ctx, struct libnet_JoinCtx);
if (!ctx) {
ctx->in.machine_name = talloc_strdup(mem_ctx, lp_netbios_name());
W_ERROR_HAVE_NO_MEMORY(ctx->in.machine_name);
- krb5_cc_env = getenv(KRB5_ENV_CCNAME);
- if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) {
- krb5_cc_env = talloc_strdup(mem_ctx, "MEMORY:libnetjoin");
- W_ERROR_HAVE_NO_MEMORY(krb5_cc_env);
- setenv(KRB5_ENV_CCNAME, krb5_cc_env, 1);
- }
-
ctx->in.secure_channel_type = SEC_CHAN_WKSTA;
*r = ctx;
struct libnet_UnjoinCtx **r)
{
struct libnet_UnjoinCtx *ctx;
- const char *krb5_cc_env = NULL;
ctx = talloc_zero(mem_ctx, struct libnet_UnjoinCtx);
if (!ctx) {
ctx->in.machine_name = talloc_strdup(mem_ctx, lp_netbios_name());
W_ERROR_HAVE_NO_MEMORY(ctx->in.machine_name);
- krb5_cc_env = getenv(KRB5_ENV_CCNAME);
- if (!krb5_cc_env || (strlen(krb5_cc_env) == 0)) {
- krb5_cc_env = talloc_strdup(mem_ctx, "MEMORY:libnetjoin");
- W_ERROR_HAVE_NO_MEMORY(krb5_cc_env);
- setenv(KRB5_ENV_CCNAME, krb5_cc_env, 1);
- }
-
*r = ctx;
return WERR_OK;
if (!valid_security) {
const char *sec = NULL;
switch (lp_security()) {
- case SEC_SHARE: sec = "share"; break;
case SEC_USER: sec = "user"; break;
case SEC_DOMAIN: sec = "domain"; break;
case SEC_ADS: sec = "ads"; break;
create_local_private_krb5_conf_for_domain(
r->out.dns_domain_name, r->out.netbios_domain_name,
- NULL, &cli->dest_ss, cli->desthost);
+ NULL, smbXcli_conn_remote_sockaddr(cli->conn),
+ smbXcli_conn_remote_name(cli->conn));
if (r->out.domain_is_ad && r->in.account_ou &&
!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
u->in.admin_account = r->in.admin_account;
u->in.admin_password = r->in.admin_password;
u->in.modify_config = r->in.modify_config;
+ u->in.use_kerberos = r->in.use_kerberos;
u->in.unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE;