summaryrefslogtreecommitdiff
path: root/source3/utils/net_ads.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-05-18 20:12:45 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:17:08 -0500
commit463e7c11711e0c511d81c892e4be621ea3bfe8b1 (patch)
treef12bbe77073176ea53a4c3784e61f119858cc823 /source3/utils/net_ads.c
parent0648638fef56a65f9389c8a98f66c57663e8c401 (diff)
downloadsamba-463e7c11711e0c511d81c892e4be621ea3bfe8b1.tar.gz
samba-463e7c11711e0c511d81c892e4be621ea3bfe8b1.tar.bz2
samba-463e7c11711e0c511d81c892e4be621ea3bfe8b1.zip
r15701: change 'net ads leave' to disable the machine account in the domain (since removal implies greater permissions that Windows clients require)
(This used to be commit ad1f947625612ef16adb69fc2cfeffc68a9a2e02)
Diffstat (limited to 'source3/utils/net_ads.c')
-rw-r--r--source3/utils/net_ads.c267
1 files changed, 55 insertions, 212 deletions
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index fc62558320..10831c878b 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -26,6 +26,7 @@
/* Macro for checking RPC error codes to make things more readable */
+#if 0
#define CHECK_RPC_ERR(rpc, msg) \
if (!NT_STATUS_IS_OK(result = rpc)) { \
DEBUG(0, (msg ": %s\n", nt_errstr(result))); \
@@ -38,6 +39,7 @@
goto done; \
}
+#endif
#ifdef HAVE_ADS
int net_ads_usage(int argc, const char **argv)
@@ -746,35 +748,70 @@ static int net_ads_status(int argc, const char **argv)
return 0;
}
+/*******************************************************************
+ Leave an AD domain. Windows XP disables the machine account.
+ We'll try the same. The old code would do an LDAP delete.
+ That only worked using the machine creds because added the machine
+ with full control to the computer object's ACL.
+*******************************************************************/
static int net_ads_leave(int argc, const char **argv)
{
ADS_STRUCT *ads = NULL;
- ADS_STATUS rc;
+ int ret = -1;
+ struct cli_state *cli = NULL;
+ TALLOC_CTX *ctx;
+ DOM_SID *dom_sid = NULL;
if (!secrets_init()) {
DEBUG(1,("Failed to initialise secrets database\n"));
return -1;
}
- if (!opt_password) {
- net_use_machine_password();
+ if (!(ctx = talloc_init("net_ads_leave"))) {
+ DEBUG(0, ("Could not initialise talloc context\n"));
+ return -1;
}
+ /* The finds a DC and takes care of getting the
+ user creds if necessary */
+
if (!(ads = ads_startup())) {
return -1;
}
- rc = ads_leave_realm(ads, global_myname());
- if (!ADS_ERR_OK(rc)) {
- d_fprintf(stderr, "Failed to delete host '%s' from the '%s' realm.\n",
+ /* make RPC calls here */
+
+ if ( !NT_STATUS_IS_OK(connect_to_ipc_krb5(&cli, &ads->ldap_ip,
+ ads->config.ldap_server_name)) )
+ {
+ goto done;
+ }
+
+ saf_store( cli->server_domain, cli->desthost );
+
+ if ( !NT_STATUS_IS_OK(netdom_get_domain_sid( ctx, cli, &dom_sid )) ) {
+ goto done;
+ }
+
+ if ( !NT_STATUS_IS_OK(netdom_leave_domain( ctx, cli, dom_sid )) ) {
+ d_printf(stderr, "Failed to disable machine account for '%s' in realm '%s'\n",
global_myname(), ads->config.realm);
- ads_destroy(&ads);
- return -1;
+ goto done;
}
+
+ d_printf("Disabled account for '%s' in realm '%s'\n",
+ global_myname(), ads->config.realm);
+
+ ret = 0;
+
+done:
+ if ( cli )
+ cli_shutdown(cli);
- d_printf("Removed '%s' from realm '%s'\n", global_myname(), ads->config.realm);
ads_destroy(&ads);
- return 0;
+ TALLOC_FREE( ctx );
+
+ return ret;
}
static int net_ads_join_ok(void)
@@ -846,203 +883,6 @@ static int check_ads_config( void )
}
/*******************************************************************
- Store the machine password and domain SID
- ********************************************************************/
-
-static int store_domain_account( const char *domain, DOM_SID *sid, const char *pw )
-{
- if (!secrets_store_domain_sid(domain, sid)) {
- DEBUG(1,("Failed to save domain sid\n"));
- return -1;
- }
-
- if (!secrets_store_machine_password(pw, domain, SEC_CHAN_WKSTA)) {
- DEBUG(1,("Failed to save machine password\n"));
- return -1;
- }
-
- return 0;
-}
-
-/*******************************************************************
- ********************************************************************/
-
-static NTSTATUS join_fetch_domain_sid( TALLOC_CTX *mem_ctx, struct cli_state *cli, DOM_SID **sid )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND lsa_pol;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- char *domain = NULL;
-
- if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_LSARPC, &status)) == NULL ) {
- DEBUG(0, ("Error connecting to LSA pipe. Error was %s\n",
- nt_errstr(status) ));
- return status;
- }
-
- status = rpccli_lsa_open_policy(pipe_hnd, mem_ctx, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED, &lsa_pol);
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
- status = rpccli_lsa_query_info_policy(pipe_hnd, mem_ctx,
- &lsa_pol, 5, &domain, sid);
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
- rpccli_lsa_close(pipe_hnd, mem_ctx, &lsa_pol);
- cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
-
- /* Bail out if domain didn't get set. */
- if (!domain) {
- DEBUG(0, ("Could not get domain name.\n"));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- Do the domain join
- ********************************************************************/
-
-static NTSTATUS join_create_machine( TALLOC_CTX *mem_ctx, struct cli_state *cli,
- DOM_SID *dom_sid, const char *clear_pw )
-{
- struct rpc_pipe_client *pipe_hnd = NULL;
- POLICY_HND sam_pol, domain_pol, user_pol;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- char *acct_name;
- const char *const_acct_name;
- uint32 user_rid;
- uint32 num_rids, *name_types, *user_rids;
- uint32 flags = 0x3e8;
- uint32 acb_info = ACB_WSTRUST;
- uchar pwbuf[516];
- SAM_USERINFO_CTR ctr;
- SAM_USER_INFO_24 p24;
- SAM_USER_INFO_16 p16;
- uchar md4_trust_password[16];
-
- /* Open the domain */
-
- if ( (pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status)) == NULL ) {
- DEBUG(0, ("Error connecting to SAM pipe. Error was %s\n",
- nt_errstr(status) ));
- return status;
- }
-
- status = rpccli_samr_connect(pipe_hnd, mem_ctx,
- SEC_RIGHTS_MAXIMUM_ALLOWED, &sam_pol);
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
-
- status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED, dom_sid, &domain_pol);
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
- /* Create domain user */
-
- acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname());
- strlower_m(acct_name);
- const_acct_name = acct_name;
-
- /* Don't try to set any acb_info flags other than ACB_WSTRUST */
-
- status = rpccli_samr_create_dom_user(pipe_hnd, mem_ctx, &domain_pol,
- acct_name, acb_info, 0xe005000b, &user_pol, &user_rid);
-
- if ( !NT_STATUS_IS_OK(status)
- && !NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS))
- {
- d_fprintf(stderr, "Creation of workstation account failed\n");
-
- /* If NT_STATUS_ACCESS_DENIED then we have a valid
- username/password combo but the user does not have
- administrator access. */
-
- if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED))
- d_fprintf(stderr, "User specified does not have administrator privileges\n");
-
- return status;
- }
-
- /* We *must* do this.... don't ask... */
-
- if (NT_STATUS_IS_OK(status)) {
- rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
- }
-
- status = rpccli_samr_lookup_names(pipe_hnd, mem_ctx,
- &domain_pol, flags, 1, &const_acct_name,
- &num_rids, &user_rids, &name_types);
- if ( !NT_STATUS_IS_OK(status) )
- return status;
-
- if ( name_types[0] != SID_NAME_USER) {
- DEBUG(0, ("%s is not a user account (type=%d)\n", acct_name, name_types[0]));
- return NT_STATUS_INVALID_WORKSTATION;
- }
-
- user_rid = user_rids[0];
-
- /* Open handle on user */
-
- status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
- SEC_RIGHTS_MAXIMUM_ALLOWED, user_rid, &user_pol);
-
- /* Create a random machine account password */
-
- E_md4hash( clear_pw, md4_trust_password);
- encode_pw_buffer(pwbuf, clear_pw, STR_UNICODE);
-
- /* Set password on machine account */
-
- ZERO_STRUCT(ctr);
- ZERO_STRUCT(p24);
-
- init_sam_user_info24(&p24, (char *)pwbuf,24);
-
- ctr.switch_value = 24;
- ctr.info.id24 = &p24;
-
- status = rpccli_samr_set_userinfo(pipe_hnd, mem_ctx, &user_pol,
- 24, &cli->user_session_key, &ctr);
-
- /* Why do we have to try to (re-)set the ACB to be the same as what
- we passed in the samr_create_dom_user() call? When a NT
- workstation is joined to a domain by an administrator the
- acb_info is set to 0x80. For a normal user with "Add
- workstations to the domain" rights the acb_info is 0x84. I'm
- not sure whether it is supposed to make a difference or not. NT
- seems to cope with either value so don't bomb out if the set
- userinfo2 level 0x10 fails. -tpot */
-
- ZERO_STRUCT(ctr);
- ctr.switch_value = 16;
- ctr.info.id16 = &p16;
-
- /* Fill in the additional account flags now */
-
- acb_info |= ACB_PWNOEXP;
-#ifndef ENCTYPE_ARCFOUR_HMAC
- acb_info |= ACB_USE_DES_KEY_ONLY;
-#endif
-
- init_sam_user_info16(&p16, acb_info);
-
- status = rpccli_samr_set_userinfo2(pipe_hnd, mem_ctx, &user_pol, 16,
- &cli->user_session_key, &ctr);
-
- rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
- cli_rpc_pipe_close(pipe_hnd); /* Done with this pipe */
-
- return status;
-}
-
-/*******************************************************************
Do the domain join
********************************************************************/
@@ -1057,12 +897,15 @@ static int net_join_domain( TALLOC_CTX *ctx, const char *servername,
saf_store( cli->server_domain, cli->desthost );
- if ( !NT_STATUS_IS_OK(join_fetch_domain_sid( ctx, cli, dom_sid )) )
+ if ( !NT_STATUS_IS_OK(netdom_get_domain_sid( ctx, cli, dom_sid )) )
goto done;
- if ( !NT_STATUS_IS_OK(join_create_machine( ctx, cli, *dom_sid, password )) )
+ if ( !NT_STATUS_IS_OK(netdom_join_domain( ctx, cli, *dom_sid,
+ password, ND_TYPE_AD )) )
+ {
goto done;
-
+ }
+
ret = 0;
done:
@@ -1270,8 +1113,8 @@ int net_ads_join(int argc, const char **argv)
neede to bootstrap winbindd's first connection to the DC to get the real
short domain name --jerry */
- if ( (store_domain_account( lp_workgroup(), domain_sid, password ) == -1)
- || (store_domain_account( short_domain_name, domain_sid, password ) == -1) )
+ if ( (netdom_store_machine_account( lp_workgroup(), domain_sid, password ) == -1)
+ || (netdom_store_machine_account( short_domain_name, domain_sid, password ) == -1) )
{
ads_destroy(&ads);
return -1;