summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libnet/libnet_join.c226
-rw-r--r--source3/libnet/libnet_join.h17
2 files changed, 239 insertions, 4 deletions
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 18421056da..68434bd391 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -218,6 +218,119 @@ static NTSTATUS do_DomainJoin(TALLOC_CTX *mem_ctx,
return status;
}
+static NTSTATUS do_DomainUnjoin(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ struct cli_state *cli = NULL;
+ struct rpc_pipe_client *pipe_hnd = NULL;
+ POLICY_HND sam_pol, domain_pol, user_pol;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+ char *acct_name;
+ uint32 flags = 0x3e8;
+ const char *const_acct_name;
+ uint32 user_rid;
+ uint32 num_rids, *name_types, *user_rids;
+ SAM_USERINFO_CTR ctr, *qctr = NULL;
+ SAM_USER_INFO_16 p16;
+
+ status = cli_full_connection(&cli, NULL, r->in.server_name,
+ NULL, 0,
+ "IPC$", "IPC",
+ r->in.admin_account,
+ NULL, //r->in.domain_name,
+ r->in.password,
+ 0, Undefined, NULL);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &status);
+ if (!pipe_hnd) {
+ goto done;
+ }
+
+ status = rpccli_samr_connect(pipe_hnd, mem_ctx,
+ SEC_RIGHTS_MAXIMUM_ALLOWED, &sam_pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_samr_open_domain(pipe_hnd, mem_ctx, &sam_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ r->in.domain_sid,
+ &domain_pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname());
+ strlower_m(acct_name);
+ const_acct_name = acct_name;
+
+ 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)) {
+ goto done;
+ }
+
+ if (name_types[0] != SID_NAME_USER) {
+ status = NT_STATUS_INVALID_WORKSTATION;
+ goto done;
+ }
+
+ user_rid = user_rids[0];
+
+ status = rpccli_samr_open_user(pipe_hnd, mem_ctx, &domain_pol,
+ SEC_RIGHTS_MAXIMUM_ALLOWED,
+ user_rid, &user_pol);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ status = rpccli_samr_query_userinfo(pipe_hnd, mem_ctx,
+ &user_pol, 16, &qctr);
+ if (!NT_STATUS_IS_OK(status)) {
+ rpccli_samr_close(pipe_hnd, mem_ctx, &user_pol);
+ goto done;
+ }
+
+ ZERO_STRUCT(ctr);
+ ctr.switch_value = 16;
+ ctr.info.id16 = &p16;
+
+ p16.acb_info = qctr->info.id16->acb_info | ACB_DISABLED;
+
+ 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);
+
+ if (!secrets_delete_machine_password_ex(lp_workgroup())) {
+ status = NT_STATUS_INTERNAL_DB_ERROR;
+ goto done;
+ }
+
+ if (!secrets_delete_domain_sid(lp_workgroup())) {
+ status = NT_STATUS_INTERNAL_DB_ERROR;
+ goto done;
+ }
+
+done:
+ rpccli_samr_close(pipe_hnd, mem_ctx, &domain_pol);
+ rpccli_samr_close(pipe_hnd, mem_ctx, &sam_pol);
+
+ cli_rpc_pipe_close(pipe_hnd);
+
+ if (cli) {
+ cli_shutdown(cli);
+ }
+
+ return status;
+}
+
static WERROR do_modify_val_config(struct registry_key *key,
const char *val_name,
const char *val_data)
@@ -233,9 +346,9 @@ static WERROR do_modify_val_config(struct registry_key *key,
return reg_setvalue(key, val_name, &val);
}
-static WERROR do_modify_vals_config(TALLOC_CTX *mem_ctx,
- struct libnet_JoinCtx *r,
- struct registry_key *key)
+static WERROR do_join_modify_vals_config(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r,
+ struct registry_key *key)
{
WERROR werr;
bool is_ad = false;
@@ -273,6 +386,24 @@ static WERROR do_modify_vals_config(TALLOC_CTX *mem_ctx,
return werr;
}
+static WERROR do_unjoin_modify_vals_config(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r,
+ struct registry_key *key)
+{
+ WERROR werr;
+
+ if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
+
+ werr = do_modify_val_config(key, "security", "user");
+ W_ERROR_NOT_OK_RETURN(werr);
+ }
+
+ reg_deletevalue(key, "realm");
+
+ return werr;
+}
+
+
static WERROR do_JoinConfig(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
@@ -303,7 +434,48 @@ static WERROR do_JoinConfig(TALLOC_CTX *mem_ctx,
return werr;
}
- werr = do_modify_vals_config(mem_ctx, r, key);
+ werr = do_join_modify_vals_config(mem_ctx, r, key);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ r->out.modified_config = true;
+ r->out.result = werr;
+
+ return werr;
+}
+
+static WERROR do_UnjoinConfig(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ WERROR werr;
+ struct registry_key *key = NULL;
+
+ if (!W_ERROR_IS_OK(r->out.result)) {
+ return r->out.result;
+ }
+
+ if (!r->in.modify_config) {
+ return WERR_OK;
+ }
+
+ if (!registry_init_regdb()) {
+ return WERR_REG_IO_FAILURE;
+ }
+
+ if (!libnet_smbconf_key_exists(mem_ctx, GLOBAL_NAME)) {
+ werr = libnet_reg_createkey_internal(mem_ctx,
+ GLOBAL_NAME, &key);
+ } else {
+ werr = libnet_smbconf_open_path(mem_ctx,
+ GLOBAL_NAME,
+ REG_KEY_WRITE, &key);
+ }
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ werr = do_unjoin_modify_vals_config(mem_ctx, r, key);
if (!W_ERROR_IS_OK(werr)) {
return werr;
}
@@ -329,6 +501,21 @@ WERROR libnet_init_JoinCtx(TALLOC_CTX *mem_ctx,
return WERR_OK;
}
+WERROR libnet_init_UnjoinCtx(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx **r)
+{
+ struct libnet_UnjoinCtx *ctx;
+
+ ctx = talloc_zero(mem_ctx, struct libnet_UnjoinCtx);
+ if (!ctx) {
+ return WERR_NOMEM;
+ }
+
+ *r = ctx;
+
+ return WERR_OK;
+}
+
WERROR libnet_Join(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
@@ -361,3 +548,34 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
return werr;
}
+
+WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ WERROR werr;
+ NTSTATUS status;
+
+ printf("libnet_Unjoin\n");
+
+ if (r->in.modify_config && !lp_include_registry_globals()) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
+
+ status = do_DomainUnjoin(mem_ctx, r);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) {
+ return WERR_SETUP_NOT_JOINED;
+ }
+ return ntstatus_to_werror(status);
+ }
+ }
+
+ werr = do_UnjoinConfig(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ return werr;
+}
diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h
index 9596733cee..46ab27e8b0 100644
--- a/source3/libnet/libnet_join.h
+++ b/source3/libnet/libnet_join.h
@@ -39,8 +39,25 @@ struct libnet_JoinCtx {
char *netbios_domain_name;
char *dns_domain_name;
char *dn;
+ struct dom_sid *domain_sid;
bool modified_config;
+ WERROR result;
+ } out;
+};
+
+struct libnet_UnjoinCtx {
+ struct {
+ const char *server_name;
+ const char *domain_name;
+ const char *admin_account;
+ const char *password;
+ uint32_t unjoin_flags;
+ bool modify_config;
struct dom_sid *domain_sid;
+ } in;
+
+ struct {
+ bool modified_config;
WERROR result;
} out;
};