mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
Store the type of 'sec channel' that we establish to the DC. If we are a
workstation, we have to use the workstation type, if we have a BDC account, we must use the BDC type - even if we are pretending to be a workstation at the moment. Also actually store and retreive the last change time, so we can do periodic password changes again (for RPC at least). And finally, a couple of minor fixes to 'net'. Andrew Bartlett
This commit is contained in:
parent
c7dc0b27ac
commit
6e6b7b79ed
@ -352,6 +352,11 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||
"Error was %s.\n", user_info->smb_name.str,
|
||||
user_info->domain.str, cli->srv_name_slash,
|
||||
nt_errstr(nt_status)));
|
||||
|
||||
/* map to something more useful */
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {
|
||||
nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
} else {
|
||||
nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str,
|
||||
user_info->smb_name.str, domain, server_info, &info3);
|
||||
@ -400,6 +405,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
unsigned char trust_passwd[16];
|
||||
time_t last_change_time;
|
||||
const char *domain = lp_workgroup();
|
||||
uint32 sec_channel_type = 0;
|
||||
|
||||
if (!user_info || !server_info || !auth_context) {
|
||||
DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
|
||||
@ -422,7 +428,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
* No need to become_root() as secrets_init() is done at startup.
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time))
|
||||
if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time, &sec_channel_type))
|
||||
{
|
||||
DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain));
|
||||
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
@ -447,7 +453,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||
nt_status = domain_client_validate(mem_ctx, user_info, domain,
|
||||
(uchar *)auth_context->challenge.data,
|
||||
server_info,
|
||||
password_server, global_myname(), SEC_CHAN_WKSTA, trust_passwd, last_change_time);
|
||||
password_server, global_myname(), sec_channel_type,trust_passwd, last_change_time);
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,9 @@
|
||||
*/
|
||||
#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
|
||||
#define SECRETS_MACHINE_PASSWORD "SECRETS/MACHINE_PASSWORD"
|
||||
|
||||
#define SECRETS_MACHINE_LAST_CHANGE_TIME "SECRETS/MACHINE_LAST_CHANGE_TIME"
|
||||
#define SECRETS_MACHINE_SEC_CHANNEL_TYPE "SECRETS/MACHINE_SEC_CHANNEL_TYPE"
|
||||
#define SECRETS_MACHINE_TRUST_ACCOUNT_NAME "SECRETS/SECRETS_MACHINE_TRUST_ACCOUNT_NAME"
|
||||
/* this one is for storing trusted domain account password */
|
||||
#define SECRETS_DOMTRUST_ACCT_PASS "SECRETS/$DOMTRUST.ACC"
|
||||
|
||||
|
@ -53,7 +53,7 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
password_s = secrets_fetch_machine_password();
|
||||
password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
|
||||
if (!password_s) {
|
||||
DEBUG(1,("failed to fetch machine password\n"));
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
|
@ -1024,6 +1024,7 @@ char *ads_ou_string(const char *org_unit)
|
||||
add a machine account to the ADS server
|
||||
*/
|
||||
static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
|
||||
uint32 account_type,
|
||||
const char *org_unit)
|
||||
{
|
||||
ADS_STATUS ret, status;
|
||||
@ -1073,7 +1074,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
|
||||
if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname)))
|
||||
goto done;
|
||||
|
||||
acct_control = UF_WORKSTATION_TRUST_ACCOUNT | UF_DONT_EXPIRE_PASSWD;
|
||||
acct_control = account_type | UF_DONT_EXPIRE_PASSWD;
|
||||
#ifndef ENCTYPE_ARCFOUR_HMAC
|
||||
acct_control |= UF_USE_DES_KEY_ONLY;
|
||||
#endif
|
||||
@ -1335,7 +1336,8 @@ int ads_count_replies(ADS_STRUCT *ads, void *res)
|
||||
* @param org_unit Organizational unit to place machine in
|
||||
* @return status of join
|
||||
**/
|
||||
ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org_unit)
|
||||
ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname,
|
||||
uint32 account_type, const char *org_unit)
|
||||
{
|
||||
ADS_STATUS status;
|
||||
LDAPMessage *res;
|
||||
@ -1356,7 +1358,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org
|
||||
}
|
||||
}
|
||||
|
||||
status = ads_add_machine_acct(ads, host, org_unit);
|
||||
status = ads_add_machine_acct(ads, host, account_type, org_unit);
|
||||
if (!ADS_ERR_OK(status)) {
|
||||
DEBUG(0, ("ads_add_machine_acct: %s\n", ads_errstr(status)));
|
||||
return status;
|
||||
|
@ -29,21 +29,23 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
|
||||
char *new_password;
|
||||
char *service_principal;
|
||||
ADS_STATUS ret;
|
||||
|
||||
if ((password = secrets_fetch_machine_password()) == NULL) {
|
||||
uint32 sec_channel_type;
|
||||
|
||||
if ((password = secrets_fetch_machine_password(lp_workgroup(), NULL, &sec_channel_type)) == NULL) {
|
||||
DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal));
|
||||
return ADS_ERROR_SYSTEM(ENOENT);
|
||||
}
|
||||
|
||||
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
||||
new_password = strdup(tmp_password);
|
||||
|
||||
asprintf(&service_principal, "HOST/%s", host_principal);
|
||||
|
||||
ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset);
|
||||
|
||||
if (!ADS_ERR_OK(ret)) goto failed;
|
||||
|
||||
if (!secrets_store_machine_password(new_password)) {
|
||||
if (!secrets_store_machine_password(new_password, lp_workgroup(), sec_channel_type)) {
|
||||
DEBUG(1,("Failed to save machine password\n"));
|
||||
return ADS_ERROR_SYSTEM(EACCES);
|
||||
}
|
||||
|
@ -31,12 +31,13 @@
|
||||
**********************************************************/
|
||||
static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
unsigned char orig_trust_passwd_hash[16],
|
||||
unsigned char new_trust_passwd_hash[16])
|
||||
unsigned char new_trust_passwd_hash[16],
|
||||
uint32 sec_channel_type)
|
||||
{
|
||||
NTSTATUS result;
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
|
||||
result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2);
|
||||
result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n",
|
||||
@ -60,7 +61,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
|
||||
**********************************************************/
|
||||
|
||||
NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
unsigned char orig_trust_passwd_hash[16])
|
||||
const char *domain,
|
||||
unsigned char orig_trust_passwd_hash[16],
|
||||
uint32 sec_channel_type)
|
||||
{
|
||||
unsigned char new_trust_passwd_hash[16];
|
||||
char *new_trust_passwd;
|
||||
@ -74,7 +77,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx
|
||||
E_md4hash(new_trust_passwd, new_trust_passwd_hash);
|
||||
|
||||
nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
|
||||
new_trust_passwd_hash);
|
||||
new_trust_passwd_hash, sec_channel_type);
|
||||
|
||||
if (NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
|
||||
@ -83,7 +86,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx
|
||||
* Return the result of trying to write the new password
|
||||
* back into the trust account file.
|
||||
*/
|
||||
if (!secrets_store_machine_password(new_trust_passwd)) {
|
||||
if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) {
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
@ -97,22 +100,26 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx
|
||||
already setup the connection to the NETLOGON pipe
|
||||
**********************************************************/
|
||||
|
||||
NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
const char *domain)
|
||||
{
|
||||
unsigned char old_trust_passwd_hash[16];
|
||||
char *up_domain;
|
||||
|
||||
uint32 sec_channel_type = 0;
|
||||
|
||||
up_domain = talloc_strdup(mem_ctx, domain);
|
||||
|
||||
if (!secrets_fetch_trust_account_password(domain,
|
||||
old_trust_passwd_hash,
|
||||
NULL)) {
|
||||
NULL, &sec_channel_type)) {
|
||||
DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash);
|
||||
return trust_pw_change_and_store_it(cli, mem_ctx, domain,
|
||||
old_trust_passwd_hash,
|
||||
sec_channel_type);
|
||||
|
||||
}
|
||||
|
||||
@ -127,35 +134,21 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *me
|
||||
|
||||
BOOL is_trusted_domain(const char* dom_name)
|
||||
{
|
||||
int enum_ctx = 0;
|
||||
const int trustdom_size = 10;
|
||||
int num_domains, i;
|
||||
TRUSTDOM **domains;
|
||||
NTSTATUS result;
|
||||
fstring trustdom_name;
|
||||
DOM_SID trustdom_sid;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
/*
|
||||
* Query the secrets db as an ultimate source of information
|
||||
* about trusted domain names. This is PDC or BDC case.
|
||||
*/
|
||||
mem_ctx = talloc_init("is_trusted_domain");
|
||||
|
||||
do {
|
||||
result = secrets_get_trusted_domains(mem_ctx, &enum_ctx, trustdom_size,
|
||||
&num_domains, &domains);
|
||||
/* compare each returned entry against incoming connection's domain */
|
||||
for (i = 0; i < num_domains; i++) {
|
||||
pull_ucs2_fstring(trustdom_name, domains[i]->name);
|
||||
if (strequal(trustdom_name, dom_name)) {
|
||||
talloc_destroy(mem_ctx);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
|
||||
char *pass = NULL;
|
||||
time_t lct;
|
||||
BOOL ret;
|
||||
|
||||
talloc_destroy(mem_ctx);
|
||||
if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
|
||||
/*
|
||||
* Query the secrets db as an ultimate source of information
|
||||
* about trusted domain names. This is PDC or BDC case.
|
||||
*/
|
||||
ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
|
||||
SAFE_FREE(pass);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Query the trustdom_cache updated periodically. The only
|
||||
|
@ -56,7 +56,7 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
|
||||
|
||||
/* the machine acct password might have change - fetch it every time */
|
||||
SAFE_FREE(ads->auth.password);
|
||||
ads->auth.password = secrets_fetch_machine_password();
|
||||
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
|
||||
|
||||
if (primary_realm) {
|
||||
SAFE_FREE(ads->auth.realm);
|
||||
|
@ -853,7 +853,9 @@ CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, DOM_SID *domain_sid,
|
||||
/* Get a handle on a netlogon pipe. This is a bit of a hack to re-use the
|
||||
netlogon pipe as no handle is returned. */
|
||||
|
||||
NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_passwd,
|
||||
NTSTATUS cm_get_netlogon_cli(const char *domain,
|
||||
const unsigned char *trust_passwd,
|
||||
uint32 sec_channel_type,
|
||||
struct cli_state **cli)
|
||||
{
|
||||
NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||
@ -876,7 +878,7 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_pass
|
||||
DEBUG(0,("cm_get_netlogon_cli: mutex grab failed for %s\n", conn->controller));
|
||||
}
|
||||
|
||||
result = cli_nt_setup_creds(conn->cli, get_sec_chan(), trust_passwd, &neg_flags, 2);
|
||||
result = cli_nt_setup_creds(conn->cli, sec_channel_type, trust_passwd, &neg_flags, 2);
|
||||
|
||||
if (got_mutex)
|
||||
secrets_named_mutex_release(lock_name);
|
||||
@ -896,7 +898,7 @@ NTSTATUS cm_get_netlogon_cli(const char *domain, const unsigned char *trust_pass
|
||||
}
|
||||
|
||||
/* Try again */
|
||||
result = cli_nt_setup_creds( conn->cli, get_sec_chan(),trust_passwd, &neg_flags, 2);
|
||||
result = cli_nt_setup_creds( conn->cli, sec_channel_type,trust_passwd, &neg_flags, 2);
|
||||
|
||||
if (got_mutex)
|
||||
secrets_named_mutex_release(lock_name);
|
||||
|
@ -34,13 +34,14 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
|
||||
uchar trust_passwd[16];
|
||||
int num_retries = 0;
|
||||
struct cli_state *cli;
|
||||
uint32 sec_channel_type;
|
||||
DEBUG(3, ("[%5d]: check machine account\n", state->pid));
|
||||
|
||||
/* Get trust account password */
|
||||
|
||||
again:
|
||||
if (!secrets_fetch_trust_account_password(
|
||||
lp_workgroup(), trust_passwd, NULL)) {
|
||||
lp_workgroup(), trust_passwd, NULL, &sec_channel_type)) {
|
||||
result = NT_STATUS_INTERNAL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@ -49,7 +50,7 @@ enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *stat
|
||||
the trust account password. */
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
|
||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, sec_channel_type, &cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
||||
@ -234,7 +235,7 @@ enum winbindd_result winbindd_netbios_name(struct winbindd_cli_state *state)
|
||||
return WINBINDD_OK;
|
||||
}
|
||||
|
||||
/* What's my name again? */
|
||||
/* Where can I find the privilaged pipe? */
|
||||
|
||||
enum winbindd_result winbindd_priv_pipe_dir(struct winbindd_cli_state *state)
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
fstring name_domain, name_user;
|
||||
unsigned char trust_passwd[16];
|
||||
time_t last_change_time;
|
||||
uint32 smb_uid_low;
|
||||
uint32 sec_channel_type;
|
||||
NET_USER_INFO_3 info3;
|
||||
struct cli_state *cli = NULL;
|
||||
uchar chal[8];
|
||||
@ -111,21 +111,20 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trust_account_password(
|
||||
lp_workgroup(), trust_passwd, &last_change_time)) {
|
||||
lp_workgroup(), trust_passwd, &last_change_time,
|
||||
&sec_channel_type)) {
|
||||
DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
|
||||
"password for domain %s\n", lp_workgroup()));
|
||||
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* We really don't care what LUID we give the user. */
|
||||
|
||||
generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
|
||||
|
||||
ZERO_STRUCT(info3);
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd, &cli);
|
||||
result = cm_get_netlogon_cli(lp_workgroup(), trust_passwd,
|
||||
sec_channel_type,
|
||||
&cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
|
||||
@ -169,6 +168,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
NTSTATUS result;
|
||||
unsigned char trust_passwd[16];
|
||||
time_t last_change_time;
|
||||
uint32 sec_channel_type;
|
||||
NET_USER_INFO_3 info3;
|
||||
struct cli_state *cli = NULL;
|
||||
TALLOC_CTX *mem_ctx = NULL;
|
||||
@ -256,7 +256,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_trust_account_password (
|
||||
contact_domain, trust_passwd, &last_change_time)) {
|
||||
contact_domain, trust_passwd, &last_change_time,
|
||||
&sec_channel_type)) {
|
||||
DEBUG(0, ("winbindd_pam_auth: could not fetch trust account "
|
||||
"password for domain %s\n", contact_domain));
|
||||
result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
|
||||
@ -266,7 +267,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
ZERO_STRUCT(info3);
|
||||
|
||||
/* Don't shut this down - it belongs to the connection cache code */
|
||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd, &cli);
|
||||
result = cm_get_netlogon_cli(contact_domain, trust_passwd, sec_channel_type, &cli);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", nt_errstr(result)));
|
||||
|
@ -78,6 +78,7 @@ static void generate_random_sid(DOM_SID *sid)
|
||||
|
||||
static BOOL pdb_generate_sam_sid(void)
|
||||
{
|
||||
DOM_SID domain_sid;
|
||||
char *fname = NULL;
|
||||
BOOL is_dc = False;
|
||||
|
||||
@ -97,8 +98,14 @@ static BOOL pdb_generate_sam_sid(void)
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_dc) {
|
||||
if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
|
||||
sid_copy(global_sam_sid, &domain_sid);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
if (secrets_fetch_domain_sid(global_myname(), global_sam_sid)) {
|
||||
DOM_SID domain_sid;
|
||||
|
||||
/* We got our sid. If not a pdc/bdc, we're done. */
|
||||
if (!is_dc)
|
||||
@ -117,11 +124,11 @@ static BOOL pdb_generate_sam_sid(void)
|
||||
|
||||
if (!sid_equal(&domain_sid, global_sam_sid)) {
|
||||
|
||||
/* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */
|
||||
/* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */
|
||||
|
||||
DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n"));
|
||||
if (!secrets_store_domain_sid(lp_workgroup(), global_sam_sid)) {
|
||||
DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n"));
|
||||
if (!secrets_store_domain_sid(global_myname(), &domain_sid)) {
|
||||
DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID for local sid as PDC/BDC.\n"));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
|
@ -221,6 +221,20 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
|
||||
return True;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Routine to get the default secure channel type for trust accounts
|
||||
************************************************************************/
|
||||
|
||||
uint32 get_default_sec_channel(void)
|
||||
{
|
||||
if (lp_server_role() == ROLE_DOMAIN_BDC ||
|
||||
lp_server_role() == ROLE_DOMAIN_PDC) {
|
||||
return SEC_CHAN_BDC;
|
||||
} else {
|
||||
return SEC_CHAN_WKSTA;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Routine to get the trust account password for a domain.
|
||||
The user of this function must have locked the trust password file using
|
||||
@ -228,19 +242,20 @@ BOOL secrets_lock_trust_account_password(const char *domain, BOOL dolock)
|
||||
************************************************************************/
|
||||
|
||||
BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
|
||||
time_t *pass_last_set_time)
|
||||
time_t *pass_last_set_time,
|
||||
uint32 *channel)
|
||||
{
|
||||
struct machine_acct_pass *pass;
|
||||
char *plaintext;
|
||||
size_t size;
|
||||
|
||||
plaintext = secrets_fetch_machine_password();
|
||||
plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
|
||||
channel);
|
||||
if (plaintext) {
|
||||
/* we have an ADS password - use that */
|
||||
DEBUG(4,("Using ADS machine password\n"));
|
||||
E_md4hash(plaintext, ret_pwd);
|
||||
SAFE_FREE(plaintext);
|
||||
pass_last_set_time = 0;
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -257,6 +272,10 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
|
||||
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
|
||||
memcpy(ret_pwd, pass->hash, 16);
|
||||
SAFE_FREE(pass);
|
||||
|
||||
if (channel)
|
||||
*channel = get_default_sec_channel();
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -369,14 +388,42 @@ BOOL secrets_store_trusted_domain_password(const char* domain, smb_ucs2_t *uni_d
|
||||
the password is assumed to be a null terminated ascii string
|
||||
************************************************************************/
|
||||
|
||||
BOOL secrets_store_machine_password(const char *pass)
|
||||
BOOL secrets_store_machine_password(const char *pass, const char *domain, uint32 sec_channel)
|
||||
{
|
||||
char *key;
|
||||
char *key = NULL;
|
||||
BOOL ret;
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, lp_workgroup());
|
||||
uint32 last_change_time;
|
||||
uint32 sec_channel_type;
|
||||
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
|
||||
if (!key)
|
||||
return False;
|
||||
strupper(key);
|
||||
|
||||
ret = secrets_store(key, pass, strlen(pass)+1);
|
||||
free(key);
|
||||
SAFE_FREE(key);
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
|
||||
if (!key)
|
||||
return False;
|
||||
strupper(key);
|
||||
|
||||
SIVAL(&last_change_time, 0, time(NULL));
|
||||
ret = secrets_store(key, &last_change_time, sizeof(last_change_time));
|
||||
SAFE_FREE(key);
|
||||
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
|
||||
if (!key)
|
||||
return False;
|
||||
strupper(key);
|
||||
|
||||
SIVAL(&sec_channel_type, 0, sec_channel);
|
||||
ret = secrets_store(key, &sec_channel_type, sizeof(sec_channel_type));
|
||||
SAFE_FREE(key);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -385,14 +432,45 @@ BOOL secrets_store_machine_password(const char *pass)
|
||||
Routine to fetch the plaintext machine account password for a realm
|
||||
the password is assumed to be a null terminated ascii string
|
||||
************************************************************************/
|
||||
char *secrets_fetch_machine_password(void)
|
||||
char *secrets_fetch_machine_password(const char *domain,
|
||||
time_t *pass_last_set_time,
|
||||
uint32 *channel)
|
||||
{
|
||||
char *key;
|
||||
char *key = NULL;
|
||||
char *ret;
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, lp_workgroup());
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_PASSWORD, domain);
|
||||
strupper(key);
|
||||
ret = (char *)secrets_fetch(key, NULL);
|
||||
free(key);
|
||||
SAFE_FREE(key);
|
||||
|
||||
if (pass_last_set_time) {
|
||||
size_t size;
|
||||
uint32 *last_set_time;
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_LAST_CHANGE_TIME, domain);
|
||||
strupper(key);
|
||||
last_set_time = secrets_fetch(key, &size);
|
||||
if (last_set_time) {
|
||||
*pass_last_set_time = IVAL(last_set_time,0);
|
||||
} else {
|
||||
*pass_last_set_time = 0;
|
||||
}
|
||||
SAFE_FREE(key);
|
||||
}
|
||||
|
||||
if (channel) {
|
||||
size_t size;
|
||||
uint32 *channel_type;
|
||||
asprintf(&key, "%s/%s", SECRETS_MACHINE_SEC_CHANNEL_TYPE, domain);
|
||||
strupper(key);
|
||||
channel_type = secrets_fetch(key, &size);
|
||||
if (channel_type) {
|
||||
*channel = IVAL(channel_type,0);
|
||||
} else {
|
||||
*channel = get_default_sec_channel();
|
||||
}
|
||||
SAFE_FREE(key);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -637,7 +715,7 @@ BOOL must_use_pdc( const char *domain )
|
||||
time_t last_change_time;
|
||||
unsigned char passwd[16];
|
||||
|
||||
if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time) )
|
||||
if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) )
|
||||
return False;
|
||||
|
||||
/*
|
||||
|
@ -227,24 +227,6 @@ password ?).\n", cli->desthost ));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return the secure channel type depending on the server role. */
|
||||
|
||||
uint16 get_sec_chan(void)
|
||||
{
|
||||
uint16 sec_chan = SEC_CHAN_WKSTA;
|
||||
|
||||
switch (lp_server_role()) {
|
||||
case ROLE_DOMAIN_PDC:
|
||||
sec_chan = SEC_CHAN_DOMAIN;
|
||||
break;
|
||||
case ROLE_DOMAIN_BDC:
|
||||
sec_chan = SEC_CHAN_BDC;
|
||||
break;
|
||||
}
|
||||
|
||||
return sec_chan;
|
||||
}
|
||||
|
||||
/* Initialize domain session credentials */
|
||||
|
||||
NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
|
||||
|
@ -152,6 +152,7 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
|
||||
SAM_DELTA_CTR *deltas;
|
||||
DOM_CRED ret_creds;
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
uint32 sec_channel_type = 0;
|
||||
|
||||
if (argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [database_id]\n", argv[0]);
|
||||
@ -169,12 +170,12 @@ static NTSTATUS cmd_netlogon_sam_sync(struct cli_state *cli,
|
||||
/* Initialise session credentials */
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
|
||||
NULL)) {
|
||||
NULL, &sec_channel_type)) {
|
||||
fprintf(stderr, "could not fetch trust account password\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2);
|
||||
result = cli_nt_setup_creds(cli, sec_channel_type, trust_passwd, &neg_flags, 2);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
fprintf(stderr, "Error initialising session creds\n");
|
||||
@ -213,6 +214,7 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
|
||||
SAM_DELTA_CTR *deltas;
|
||||
UINT64_S seqnum;
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
uint32 sec_channel_type = 0;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s database_id seqnum\n", argv[0]);
|
||||
@ -233,12 +235,12 @@ static NTSTATUS cmd_netlogon_sam_deltas(struct cli_state *cli,
|
||||
/* Initialise session credentials */
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd,
|
||||
NULL)) {
|
||||
NULL, &sec_channel_type)) {
|
||||
fprintf(stderr, "could not fetch trust account password\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = cli_nt_setup_creds(cli, get_sec_chan(), trust_passwd, &neg_flags, 2);
|
||||
result = cli_nt_setup_creds(cli, sec_channel_type, trust_passwd, &neg_flags, 2);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
fprintf(stderr, "Error initialising session creds\n");
|
||||
|
@ -393,15 +393,16 @@ static NTSTATUS do_cmd(struct cli_state *cli,
|
||||
|
||||
if (cmd_entry->pipe_idx == PI_NETLOGON) {
|
||||
uchar trust_password[16];
|
||||
uint32 sec_channel_type;
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_password,
|
||||
NULL)) {
|
||||
NULL, &sec_channel_type)) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!cli_nt_open_netlogon(cli, trust_password,
|
||||
SEC_CHAN_WKSTA)) {
|
||||
sec_channel_type)) {
|
||||
DEBUG(0, ("Could not initialise NETLOGON pipe\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
@ -24,78 +24,16 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
/*********************************************************
|
||||
Change the domain password on the PDC.
|
||||
**********************************************************/
|
||||
|
||||
static NTSTATUS modify_trust_password( const char *domain, const char *remote_machine,
|
||||
unsigned char orig_trust_passwd_hash[16])
|
||||
{
|
||||
struct cli_state *cli;
|
||||
DOM_SID domain_sid;
|
||||
NTSTATUS nt_status;
|
||||
|
||||
/*
|
||||
* Ensure we have the domain SID for this domain.
|
||||
*/
|
||||
|
||||
if (!secrets_fetch_domain_sid(domain, &domain_sid)) {
|
||||
DEBUG(0, ("modify_trust_password: unable to fetch domain sid.\n"));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), remote_machine,
|
||||
NULL, 0,
|
||||
"IPC$", "IPC",
|
||||
"", "",
|
||||
"", 0, NULL)))
|
||||
{
|
||||
DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok - we have an anonymous connection to the IPC$ share.
|
||||
* Now start the NT Domain stuff :-).
|
||||
*/
|
||||
|
||||
if(cli_nt_session_open(cli, PI_NETLOGON) == False) {
|
||||
DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
|
||||
remote_machine, cli_errstr(cli)));
|
||||
cli_nt_session_close(cli);
|
||||
cli_ulogoff(cli);
|
||||
cli_shutdown(cli);
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
nt_status = trust_pw_change_and_store_it(cli, cli->mem_ctx,
|
||||
orig_trust_passwd_hash);
|
||||
|
||||
cli_nt_session_close(cli);
|
||||
cli_ulogoff(cli);
|
||||
cli_shutdown(cli);
|
||||
|
||||
return nt_status;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Change the trust account password for a domain.
|
||||
************************************************************************/
|
||||
|
||||
NTSTATUS change_trust_account_password( const char *domain, const char *remote_machine)
|
||||
{
|
||||
unsigned char old_trust_passwd_hash[16];
|
||||
time_t lct;
|
||||
NTSTATUS res = NT_STATUS_UNSUCCESSFUL;
|
||||
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
struct in_addr pdc_ip;
|
||||
fstring dc_name;
|
||||
|
||||
|
||||
if(!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, &lct)) {
|
||||
DEBUG(0,("change_trust_account_password: unable to read the machine account password for domain %s.\n",
|
||||
domain));
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
struct cli_state *cli;
|
||||
|
||||
if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
|
||||
/* Use the PDC *only* for this */
|
||||
@ -116,13 +54,44 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
|
||||
/* if this next call fails, then give up. We can't do
|
||||
password changes on BDC's --jerry */
|
||||
|
||||
res = modify_trust_password(domain, dc_name, old_trust_passwd_hash);
|
||||
if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), remote_machine,
|
||||
NULL, 0,
|
||||
"IPC$", "IPC",
|
||||
"", "",
|
||||
"", 0, NULL)))
|
||||
{
|
||||
DEBUG(0,("modify_trust_password: Connection to %s failed!\n", remote_machine));
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ok - we have an anonymous connection to the IPC$ share.
|
||||
* Now start the NT Domain stuff :-).
|
||||
*/
|
||||
|
||||
if(cli_nt_session_open(cli, PI_NETLOGON) == False) {
|
||||
DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
|
||||
remote_machine, cli_errstr(cli)));
|
||||
cli_nt_session_close(cli);
|
||||
cli_ulogoff(cli);
|
||||
cli_shutdown(cli);
|
||||
nt_status = NT_STATUS_UNSUCCESSFUL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
nt_status = trust_pw_find_change_and_store_it(cli, cli->mem_ctx,
|
||||
domain);
|
||||
|
||||
cli_nt_session_close(cli);
|
||||
cli_ulogoff(cli);
|
||||
cli_shutdown(cli);
|
||||
|
||||
failed:
|
||||
if (!NT_STATUS_IS_OK(res)) {
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n",
|
||||
timestring(False), domain));
|
||||
}
|
||||
|
||||
return res;
|
||||
return nt_status;
|
||||
}
|
||||
|
@ -1179,9 +1179,11 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
|
||||
return True;
|
||||
}
|
||||
|
||||
if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct)) {
|
||||
if(!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_passwd_hash,
|
||||
&lct, NULL)) {
|
||||
DEBUG(0,("process: unable to read the machine account password for \
|
||||
machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
|
||||
machine %s in domain %s.\n", global_myname(), lp_workgroup()));
|
||||
secrets_lock_trust_account_password(lp_workgroup(), False);
|
||||
return True;
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ int opt_force = 0;
|
||||
int opt_port = 0;
|
||||
int opt_maxusers = -1;
|
||||
const char *opt_comment = "";
|
||||
char *opt_container = "cn=Users";
|
||||
const char *opt_container = "cn=Users";
|
||||
int opt_flags = -1;
|
||||
int opt_timeout = 0;
|
||||
const char *opt_target_workgroup = NULL;
|
||||
@ -77,6 +77,27 @@ static int opt_machine_pass = 0;
|
||||
BOOL opt_have_ip = False;
|
||||
struct in_addr opt_dest_ip;
|
||||
|
||||
uint32 get_sec_channel_type(const char *param)
|
||||
{
|
||||
if (param && *param) {
|
||||
return get_default_sec_channel();
|
||||
} else {
|
||||
if (strcasecmp(param, "PDC")==0) {
|
||||
return SEC_CHAN_BDC;
|
||||
} else if (strcasecmp(param, "BDC")==0) {
|
||||
return SEC_CHAN_BDC;
|
||||
} else if (strcasecmp(param, "MEMBER")==0) {
|
||||
return SEC_CHAN_WKSTA;
|
||||
#if 0
|
||||
} else if (strcasecmp(param, "DOMAIN")==0) {
|
||||
return SEC_CHAN_DOMAIN;
|
||||
#endif
|
||||
} else {
|
||||
return get_default_sec_channel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
run a function from a function table. If not found then
|
||||
call the specified usage function
|
||||
@ -602,11 +623,11 @@ static struct functable net_func[] = {
|
||||
}
|
||||
|
||||
if (!opt_workgroup) {
|
||||
opt_workgroup = lp_workgroup();
|
||||
opt_workgroup = smb_xstrdup(lp_workgroup());
|
||||
}
|
||||
|
||||
if (!opt_target_workgroup) {
|
||||
opt_target_workgroup = strdup(lp_workgroup());
|
||||
opt_target_workgroup = smb_xstrdup(lp_workgroup());
|
||||
}
|
||||
|
||||
if (!init_names())
|
||||
@ -615,7 +636,7 @@ static struct functable net_func[] = {
|
||||
load_interfaces();
|
||||
|
||||
if (opt_machine_pass) {
|
||||
char *user;
|
||||
char *user = NULL;
|
||||
/* it is very useful to be able to make ads queries as the
|
||||
machine account for testing purposes and for domain leave */
|
||||
|
||||
@ -624,9 +645,10 @@ static struct functable net_func[] = {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
opt_password = secrets_fetch_machine_password(opt_workgroup, NULL, NULL);
|
||||
|
||||
asprintf(&user,"%s$", global_myname());
|
||||
opt_user_name = user;
|
||||
opt_password = secrets_fetch_machine_password();
|
||||
if (!opt_password) {
|
||||
d_printf("ERROR: Unable to fetch machine password\n");
|
||||
exit(1);
|
||||
|
@ -38,7 +38,7 @@
|
||||
|
||||
extern int opt_maxusers;
|
||||
extern const char *opt_comment;
|
||||
extern char *opt_container;
|
||||
extern const char *opt_container;
|
||||
extern int opt_flags;
|
||||
|
||||
extern const char *opt_comment;
|
||||
|
@ -575,7 +575,7 @@ static int net_ads_leave(int argc, const char **argv)
|
||||
if (!opt_password) {
|
||||
char *user_name;
|
||||
asprintf(&user_name, "%s$", global_myname());
|
||||
opt_password = secrets_fetch_machine_password();
|
||||
opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
|
||||
opt_user_name = user_name;
|
||||
}
|
||||
|
||||
@ -607,7 +607,7 @@ static int net_ads_join_ok(void)
|
||||
|
||||
asprintf(&user_name, "%s$", global_myname());
|
||||
opt_user_name = user_name;
|
||||
opt_password = secrets_fetch_machine_password();
|
||||
opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
|
||||
|
||||
if (!(ads = ads_startup())) {
|
||||
return -1;
|
||||
@ -648,6 +648,8 @@ int net_ads_join(int argc, const char **argv)
|
||||
void *res;
|
||||
DOM_SID dom_sid;
|
||||
char *ou_str;
|
||||
uint32 sec_channel_type;
|
||||
uint32 account_type = UF_WORKSTATION_TRUST_ACCOUNT;
|
||||
|
||||
if (argc > 0) org_unit = argv[0];
|
||||
|
||||
@ -656,6 +658,11 @@ int net_ads_join(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check what type of join
|
||||
TODO: make this variable like RPC
|
||||
*/
|
||||
account_type = UF_WORKSTATION_TRUST_ACCOUNT;
|
||||
|
||||
tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
||||
password = strdup(tmp_password);
|
||||
|
||||
@ -680,7 +687,7 @@ int net_ads_join(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ads_join_realm(ads, global_myname(), org_unit);
|
||||
rc = ads_join_realm(ads, global_myname(), account_type, org_unit);
|
||||
if (!ADS_ERR_OK(rc)) {
|
||||
d_printf("ads_join_realm: %s\n", ads_errstr(rc));
|
||||
return -1;
|
||||
@ -703,7 +710,7 @@ int net_ads_join(int argc, const char **argv)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!secrets_store_machine_password(password)) {
|
||||
if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) {
|
||||
DEBUG(1,("Failed to save machine password\n"));
|
||||
return -1;
|
||||
}
|
||||
@ -956,7 +963,7 @@ int net_ads_changetrustpw(int argc, const char **argv)
|
||||
asprintf(&user_name, "%s$", global_myname());
|
||||
opt_user_name = user_name;
|
||||
|
||||
opt_password = secrets_fetch_machine_password();
|
||||
opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
|
||||
|
||||
use_in_memory_ccache();
|
||||
|
||||
|
@ -235,8 +235,9 @@ int net_rpc_changetrustpw(int argc, const char **argv)
|
||||
* @return Normal NTSTATUS return.
|
||||
**/
|
||||
|
||||
static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli, TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv) {
|
||||
static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cli_state *cli,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
int argc, const char **argv) {
|
||||
|
||||
fstring trust_passwd;
|
||||
unsigned char orig_trust_passwd_hash[16];
|
||||
@ -254,10 +255,22 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
|
||||
|
||||
E_md4hash(trust_passwd, orig_trust_passwd_hash);
|
||||
|
||||
result = trust_pw_change_and_store_it(cli, mem_ctx, orig_trust_passwd_hash);
|
||||
result = trust_pw_change_and_store_it(cli, mem_ctx, opt_target_workgroup,
|
||||
orig_trust_passwd_hash,
|
||||
SEC_CHAN_WKSTA);
|
||||
|
||||
/* SEC_CHAN_WKSTA specified specifically, as you cannot use this
|
||||
to join a BDC to the domain (MS won't allow it, and is *really*
|
||||
insecure) */
|
||||
|
||||
if (NT_STATUS_IS_OK(result))
|
||||
printf("Joined domain %s.\n",lp_workgroup());
|
||||
printf("Joined domain %s.\n",opt_target_workgroup);
|
||||
|
||||
|
||||
if (!secrets_store_domain_sid(opt_target_workgroup, domain_sid)) {
|
||||
DEBUG(0, ("error storing domain sid for %s\n", opt_target_workgroup));
|
||||
result = NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -274,7 +287,38 @@ static NTSTATUS rpc_join_oldstyle_internals(const DOM_SID *domain_sid, struct cl
|
||||
|
||||
static int net_rpc_join_oldstyle(int argc, const char **argv)
|
||||
{
|
||||
return run_rpc_command(NULL, PI_NETLOGON, NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC, rpc_join_oldstyle_internals,
|
||||
uint32 sec_channel_type;
|
||||
/* check what type of join */
|
||||
if (argc >= 0) {
|
||||
sec_channel_type = get_sec_channel_type(argv[0]);
|
||||
} else {
|
||||
sec_channel_type = get_sec_channel_type(NULL);
|
||||
}
|
||||
|
||||
if (sec_channel_type != SEC_CHAN_WKSTA)
|
||||
return 1;
|
||||
|
||||
return run_rpc_command(NULL, PI_NETLOGON,
|
||||
NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
|
||||
rpc_join_oldstyle_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a domain, the old way.
|
||||
*
|
||||
* @param argc Standard main() style argc
|
||||
* @param argc Standard main() style argv. Initial components are already
|
||||
* stripped
|
||||
*
|
||||
* @return A shell status integer (0 for success)
|
||||
**/
|
||||
|
||||
static int net_rpc_oldjoin(int argc, const char **argv)
|
||||
{
|
||||
return run_rpc_command(NULL, PI_NETLOGON,
|
||||
NET_FLAGS_ANONYMOUS | NET_FLAGS_PDC,
|
||||
rpc_join_oldstyle_internals,
|
||||
argc, argv);
|
||||
}
|
||||
|
||||
@ -287,11 +331,13 @@ static int net_rpc_join_oldstyle(int argc, const char **argv)
|
||||
|
||||
static int rpc_join_usage(int argc, const char **argv)
|
||||
{
|
||||
d_printf("net rpc join -U <username>[%%password] [options]\n"\
|
||||
d_printf("net rpc join -U <username>[%%password] <type>[options]\n"\
|
||||
"\t to join a domain with admin username & password\n"\
|
||||
"\t\t password will be prompted if none is specified\n");
|
||||
d_printf("net rpc join [options except -U]\n"\
|
||||
"\t to join a domain created in server manager\n\n\n");
|
||||
"\t\t password will be prompted if needed and none is specified\n"\
|
||||
"\t <type> can be (default MEMBER)\n"\
|
||||
"\t\t BDC - Join as a BDC\n"\
|
||||
"\t\t PDC - Join as a PDC\n"\
|
||||
"\t\t MEMBER - Join as a MEMBER server\n");
|
||||
|
||||
net_common_flags_usage(argc, argv);
|
||||
return -1;
|
||||
@ -311,19 +357,10 @@ static int rpc_join_usage(int argc, const char **argv)
|
||||
|
||||
int net_rpc_join(int argc, const char **argv)
|
||||
{
|
||||
struct functable func[] = {
|
||||
{"oldstyle", net_rpc_join_oldstyle},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (argc == 0) {
|
||||
if ((net_rpc_join_oldstyle(argc, argv) == 0))
|
||||
return 0;
|
||||
|
||||
return net_rpc_join_newstyle(argc, argv);
|
||||
}
|
||||
|
||||
return net_run_function(argc, argv, func, rpc_join_usage);
|
||||
if ((net_rpc_join_oldstyle(argc, argv) == 0))
|
||||
return 0;
|
||||
|
||||
return net_rpc_join_newstyle(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
@ -2179,6 +2216,7 @@ int net_rpc_usage(int argc, const char **argv)
|
||||
{
|
||||
d_printf(" net rpc info \t\t\tshow basic info about a domain \n");
|
||||
d_printf(" net rpc join \t\t\tto join a domain \n");
|
||||
d_printf(" net rpc oldjoin \t\t\tto join a domain created in server manager\n\n\n");
|
||||
d_printf(" net rpc testjoin \t\ttests that a join is valid\n");
|
||||
d_printf(" net rpc user \t\t\tto add, delete and list users\n");
|
||||
d_printf(" net rpc group \t\tto list groups\n");
|
||||
@ -2245,6 +2283,7 @@ int net_rpc(int argc, const char **argv)
|
||||
struct functable func[] = {
|
||||
{"info", net_rpc_info},
|
||||
{"join", net_rpc_join},
|
||||
{"oldjoin", net_rpc_oldjoin},
|
||||
{"testjoin", net_rpc_testjoin},
|
||||
{"user", net_rpc_user},
|
||||
{"group", net_rpc_group},
|
||||
|
@ -62,18 +62,12 @@ int net_rpc_join_ok(const char *domain)
|
||||
}
|
||||
|
||||
if (!secrets_fetch_trust_account_password(domain,
|
||||
stored_md4_trust_password, NULL)) {
|
||||
stored_md4_trust_password,
|
||||
NULL, &channel)) {
|
||||
DEBUG(0,("Could not retreive domain trust secret"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (lp_server_role() == ROLE_DOMAIN_BDC ||
|
||||
lp_server_role() == ROLE_DOMAIN_PDC) {
|
||||
channel = SEC_CHAN_BDC;
|
||||
} else {
|
||||
channel = SEC_CHAN_WKSTA;
|
||||
}
|
||||
|
||||
CHECK_RPC_ERR(cli_nt_setup_creds(cli,
|
||||
channel,
|
||||
stored_md4_trust_password, &neg_flags, 2),
|
||||
@ -108,7 +102,8 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
|
||||
struct cli_state *cli;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
uint32 acb_info;
|
||||
uint32 acb_info = ACB_WSTRUST;
|
||||
uint32 sec_channel_type;
|
||||
|
||||
/* rpc variables */
|
||||
|
||||
@ -121,10 +116,11 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
char *clear_trust_password = NULL;
|
||||
fstring ucs2_trust_password;
|
||||
int ucs2_pw_len;
|
||||
uchar pwbuf[516], sess_key[16];
|
||||
uchar pwbuf[516];
|
||||
SAM_USERINFO_CTR ctr;
|
||||
SAM_USER_INFO_24 p24;
|
||||
SAM_USER_INFO_10 p10;
|
||||
uchar md4_trust_password[16];
|
||||
|
||||
/* Misc */
|
||||
|
||||
@ -135,6 +131,25 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
uint32 flags = 0x3e8;
|
||||
char *acct_name;
|
||||
const char *const_acct_name;
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
|
||||
/* check what type of join */
|
||||
if (argc >= 0) {
|
||||
sec_channel_type = get_sec_channel_type(argv[0]);
|
||||
} else {
|
||||
sec_channel_type = get_sec_channel_type(NULL);
|
||||
}
|
||||
|
||||
switch (sec_channel_type) {
|
||||
case SEC_CHAN_WKSTA:
|
||||
acb_info = ACB_WSTRUST;
|
||||
case SEC_CHAN_BDC:
|
||||
acb_info = ACB_SVRTRUST;
|
||||
#if 0
|
||||
case SEC_CHAN_DOMAIN:
|
||||
acb_info = ACB_DOMTRUST;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Connect to remote machine */
|
||||
|
||||
@ -189,8 +204,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
strlower(acct_name);
|
||||
const_acct_name = acct_name;
|
||||
|
||||
acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST;
|
||||
|
||||
result = cli_samr_create_dom_user(cli, mem_ctx, &domain_pol,
|
||||
acct_name, acb_info,
|
||||
0xe005000b, &user_pol,
|
||||
@ -245,6 +258,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
char *str;
|
||||
str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
|
||||
clear_trust_password = strdup(str);
|
||||
E_md4hash(clear_trust_password, md4_trust_password);
|
||||
}
|
||||
|
||||
ucs2_pw_len = push_ucs2(NULL, ucs2_trust_password,
|
||||
@ -287,8 +301,22 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
as a normal user with "Add workstation to domain" privilege. */
|
||||
|
||||
result = cli_samr_set_userinfo2(cli, mem_ctx, &user_pol, 0x10,
|
||||
sess_key, &ctr);
|
||||
cli->user_session_key, &ctr);
|
||||
|
||||
/* Now check the whole process from top-to-bottom */
|
||||
cli_samr_close(cli, mem_ctx, &user_pol);
|
||||
cli_nt_session_close(cli); /* Done with this pipe */
|
||||
|
||||
if (!cli_nt_session_open(cli, PI_NETLOGON)) {
|
||||
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
CHECK_RPC_ERR(cli_nt_setup_creds(cli,
|
||||
sec_channel_type,
|
||||
md4_trust_password, &neg_flags, 2),
|
||||
"error in domain join verification");
|
||||
|
||||
/* Now store the secret in the secrets database */
|
||||
|
||||
strupper(domain);
|
||||
@ -298,14 +326,11 @@ int net_rpc_join_newstyle(int argc, const char **argv)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!secrets_store_machine_password(clear_trust_password)) {
|
||||
if (!secrets_store_machine_password(clear_trust_password, domain, sec_channel_type)) {
|
||||
DEBUG(0, ("error storing plaintext domain secrets for %s\n", domain));
|
||||
}
|
||||
|
||||
/* Now check the whole process from top-to-bottom */
|
||||
cli_samr_close(cli, mem_ctx, &user_pol);
|
||||
cli_nt_session_close(cli); /* Done with this pipe */
|
||||
|
||||
/* double-check, connection from scratch */
|
||||
retval = net_rpc_join_ok(domain);
|
||||
|
||||
done:
|
||||
@ -317,7 +342,6 @@ done:
|
||||
/* Display success or failure */
|
||||
|
||||
if (retval != 0) {
|
||||
trust_password_delete(domain);
|
||||
fprintf(stderr,"Unable to join domain %s.\n",domain);
|
||||
} else {
|
||||
printf("Joined domain %s.\n",domain);
|
||||
|
@ -198,6 +198,7 @@ int rpc_samdump(int argc, const char **argv)
|
||||
struct cli_state *cli = NULL;
|
||||
uchar trust_password[16];
|
||||
DOM_CRED ret_creds;
|
||||
uint32 sec_channel;
|
||||
|
||||
ZERO_STRUCT(ret_creds);
|
||||
|
||||
@ -210,12 +211,12 @@ int rpc_samdump(int argc, const char **argv)
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_password,
|
||||
NULL)) {
|
||||
NULL, &sec_channel)) {
|
||||
DEBUG(0,("Could not fetch trust account password\n"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!cli_nt_open_netlogon(cli, trust_password, SEC_CHAN_BDC)) {
|
||||
if (!cli_nt_open_netlogon(cli, trust_password, sec_channel)) {
|
||||
DEBUG(0,("Error connecting to NETLOGON pipe\n"));
|
||||
goto fail;
|
||||
}
|
||||
@ -810,6 +811,7 @@ int rpc_vampire(int argc, const char **argv)
|
||||
DOM_CRED ret_creds;
|
||||
uint32 neg_flags = 0x000001ff;
|
||||
DOM_SID dom_sid;
|
||||
uint32 sec_channel;
|
||||
|
||||
ZERO_STRUCT(ret_creds);
|
||||
|
||||
@ -825,12 +827,13 @@ int rpc_vampire(int argc, const char **argv)
|
||||
}
|
||||
|
||||
if (!secrets_fetch_trust_account_password(lp_workgroup(),
|
||||
trust_password, NULL)) {
|
||||
trust_password, NULL,
|
||||
&sec_channel)) {
|
||||
d_printf("Could not retrieve domain trust secret\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = cli_nt_setup_creds(cli, SEC_CHAN_BDC, trust_password,
|
||||
result = cli_nt_setup_creds(cli, sec_channel, trust_password,
|
||||
&neg_flags, 2);
|
||||
if (!NT_STATUS_IS_OK(result)) {
|
||||
d_printf("Failed to setup BDC creds\n");
|
||||
|
Loading…
Reference in New Issue
Block a user