mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
Add libnet_Unjoin(), libnet_UnjoinCtx and friends.
Guenther
This commit is contained in:
parent
96ebdca45b
commit
89e8abb116
@ -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;
|
||||
}
|
||||
|
@ -39,8 +39,25 @@ struct libnet_JoinCtx {
|
||||
char *netbios_domain_name;
|
||||
char *dns_domain_name;
|
||||
char *dn;
|
||||
bool modified_config;
|
||||
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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user