1
0
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:
Günther Deschner 2007-12-19 11:02:39 +01:00
parent 96ebdca45b
commit 89e8abb116
2 changed files with 240 additions and 5 deletions

View File

@ -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;
}

View File

@ -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;
};