WERROR NetRemoteTOD_r(struct libnetapi_ctx *ctx, struct NetRemoteTOD *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; struct srvsvc_NetRemoteTODInfo *info = NULL; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_srvsvc_NetRemoteTOD(pipe_cli, talloc_tos(), r->in.server_name, &info, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } *r->out.buffer = (uint8_t *)talloc_memdup(ctx, info, sizeof(struct srvsvc_NetRemoteTODInfo)); W_ERROR_HAVE_NO_MEMORY(*r->out.buffer); done: return werr; }
WERROR NetGetAnyDCName_r(struct libnetapi_ctx *ctx, struct NetGetAnyDCName *r) { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_netlogon.syntax_id, &cli, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_netr_GetAnyDCName(pipe_cli, ctx, r->in.server_name, r->in.domain_name, (const char **)r->out.buffer, &werr); if (!NT_STATUS_IS_OK(status)) { goto done; } done: return werr; }
WERROR NetShareDel_r(struct libnetapi_ctx *ctx, struct NetShareDel *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; if (!r->in.net_name) { return WERR_INVALID_PARAM; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_srvsvc_NetShareDel(pipe_cli, ctx, r->in.server_name, r->in.net_name, r->in.reserved, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx, struct NetGetJoinInformation *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; const char *buffer = NULL; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_wkssvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_wkssvc_NetrGetJoinInformation(pipe_cli, talloc_tos(), r->in.server_name, &buffer, (enum wkssvc_NetJoinStatus *)r->out.name_type, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } *r->out.name_buffer = talloc_strdup(ctx, buffer); W_ERROR_HAVE_NO_MEMORY(*r->out.name_buffer); done: return werr; }
WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx, struct NetJoinDomain *r) { struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; unsigned int old_timeout = 0; struct dcerpc_binding_handle *b; DATA_BLOB session_key; if (IS_DC) { return WERR_NERR_SETUPDOMAINCONTROLLER; } werr = libnetapi_open_pipe(ctx, r->in.server, &ndr_table_wkssvc, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; if (r->in.password) { status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } encode_wkssvc_join_password_buffer(ctx, r->in.password, &session_key, &encrypted_password); } old_timeout = rpccli_set_timeout(pipe_cli, 600000); status = dcerpc_wkssvc_NetrJoinDomain2(b, talloc_tos(), r->in.server, r->in.domain, r->in.account_ou, r->in.account, encrypted_password, r->in.join_flags, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: if (pipe_cli && old_timeout) { rpccli_set_timeout(pipe_cli, old_timeout); } return werr; }
WERROR NetFileClose_r(struct libnetapi_ctx *ctx, struct NetFileClose *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_srvsvc_NetFileClose(pipe_cli, talloc_tos(), r->in.server_name, r->in.fileid, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR DsGetDcName_r(struct libnetapi_ctx *ctx, struct DsGetDcName *r) { WERROR werr; NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_netlogon.syntax_id, &cli, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_netr_DsRGetDCName(pipe_cli, ctx, r->in.server_name, r->in.domain_name, r->in.domain_guid, NULL, r->in.flags, (struct netr_DsRGetDCNameInfo **)r->out.dc_info, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetShareSetInfo_r(struct libnetapi_ctx *ctx, struct NetShareSetInfo *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; union srvsvc_NetShareInfo info; if (!r->in.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 2: case 1004: break; case 1: case 502: case 503: case 1005: case 1006: case 1501: return WERR_NOT_SUPPORTED; default: return WERR_UNKNOWN_LEVEL; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = map_SHARE_INFO_buffer_to_srvsvc_share_info(ctx, r->in.buffer, r->in.level, &info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } status = rpccli_srvsvc_NetShareSetInfo(pipe_cli, ctx, r->in.server_name, r->in.net_name, r->in.level, &info, r->out.parm_err, &werr); if (!W_ERROR_IS_OK(werr)) { goto done; } done: return werr; }
WERROR NetServerGetInfo_r(struct libnetapi_ctx *ctx, struct NetServerGetInfo *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; union srvsvc_NetSrvInfo info; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 100: case 101: case 102: case 402: case 502: case 503: case 1005: break; default: return WERR_UNKNOWN_LEVEL; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_srvsvc_NetSrvGetInfo(pipe_cli, talloc_tos(), r->in.server_name, r->in.level, &info, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } status = map_server_info_to_SERVER_INFO_buffer(ctx, r->in.level, &info, r->out.buffer); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetFileGetInfo_r(struct libnetapi_ctx *ctx, struct NetFileGetInfo *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; union srvsvc_NetFileInfo info; uint32_t num_entries = 0; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 2: case 3: break; default: return WERR_UNKNOWN_LEVEL; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } status = rpccli_srvsvc_NetFileGetInfo(pipe_cli, talloc_tos(), r->in.server_name, r->in.fileid, r->in.level, &info, &werr); if (!W_ERROR_IS_OK(werr)) { goto done; } status = map_srvsvc_FileInfo_to_FILE_INFO_buffer(ctx, r->in.level, &info, r->out.buffer, &num_entries); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx, struct NetGetJoinableOUs *r) { struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; struct dcerpc_binding_handle *b; DATA_BLOB session_key; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_wkssvc, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; if (r->in.password) { status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } encode_wkssvc_join_password_buffer(ctx, r->in.password, &session_key, &encrypted_password); } status = dcerpc_wkssvc_NetrGetJoinableOus2(b, talloc_tos(), r->in.server_name, r->in.domain, r->in.account, encrypted_password, r->out.ou_count, r->out.ous, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx, struct NetJoinDomain *r) { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; unsigned int old_timeout = 0; werr = libnetapi_open_pipe(ctx, r->in.server, &ndr_table_wkssvc.syntax_id, &cli, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } if (r->in.password) { encode_wkssvc_join_password_buffer(ctx, r->in.password, &cli->user_session_key, &encrypted_password); } old_timeout = cli_set_timeout(cli, 600000); status = rpccli_wkssvc_NetrJoinDomain2(pipe_cli, ctx, r->in.server, r->in.domain, r->in.account_ou, r->in.account, encrypted_password, r->in.join_flags, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: if (cli) { if (old_timeout) { cli_set_timeout(cli, old_timeout); } } return werr; }
WERROR libnetapi_get_binding_handle(struct libnetapi_ctx *ctx, const char *server_name, const struct ndr_syntax_id *interface, struct dcerpc_binding_handle **binding_handle) { struct rpc_pipe_client *pipe_cli; WERROR result; *binding_handle = NULL; result = libnetapi_open_pipe(ctx, server_name, interface, &pipe_cli); if (!W_ERROR_IS_OK(result)) { return result; } *binding_handle = pipe_cli->binding_handle; return WERR_OK; }
WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx, struct NetGetJoinableOUs *r) { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_wkssvc.syntax_id, &cli, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } if (r->in.password) { encode_wkssvc_join_password_buffer(ctx, r->in.password, &cli->user_session_key, &encrypted_password); } status = rpccli_wkssvc_NetrGetJoinableOus2(pipe_cli, ctx, r->in.server_name, r->in.domain, r->in.account, encrypted_password, r->out.ou_count, r->out.ous, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetServerSetInfo_r(struct libnetapi_ctx *ctx, struct NetServerSetInfo *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; union srvsvc_NetSrvInfo info; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } switch (r->in.level) { case 1005: info.info1005 = (struct srvsvc_NetSrvInfo1005 *)r->in.buffer; break; default: werr = WERR_NOT_SUPPORTED; goto done; } status = rpccli_srvsvc_NetSrvSetInfo(pipe_cli, talloc_tos(), r->in.server_name, r->in.level, &info, r->out.parm_error, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx, struct NetRenameMachineInDomain *r) { struct rpc_pipe_client *pipe_cli = NULL; struct wkssvc_PasswordBuffer *encrypted_password = NULL; NTSTATUS status; WERROR werr; werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_wkssvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } if (r->in.password) { encode_wkssvc_join_password_buffer(ctx, r->in.password, &pipe_cli->auth->user_session_key, &encrypted_password); } status = rpccli_wkssvc_NetrRenameMachineInDomain2(pipe_cli, talloc_tos(), r->in.server_name, r->in.new_machine_name, r->in.account, encrypted_password, r->in.rename_options, &werr); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } done: return werr; }
WERROR NetLocalGroupGetInfo_r(struct libnetapi_ctx *ctx, struct NetLocalGroupGetInfo *r) { struct cli_state *cli = NULL; struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; union samr_AliasInfo *alias_info = NULL; uint32_t entries_read = 0; if (!r->in.group_name) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: case 1002: break; default: return WERR_UNKNOWN_LEVEL; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr.syntax_id, &cli, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &builtin_handle, r->in.group_name, SAMR_ALIAS_ACCESS_LOOKUP_INFO, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); } if (NT_STATUS_IS_OK(status)) { goto query_alias; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, SAMR_DOMAIN_ACCESS_CREATE_ALIAS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &domain_handle, r->in.group_name, SAMR_ALIAS_ACCESS_LOOKUP_INFO, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); } if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } query_alias: status = rpccli_samr_QueryAliasInfo(pipe_cli, ctx, &alias_handle, ALIASINFOALL, &alias_info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } werr = map_alias_info_to_buffer(ctx, r->in.group_name, &alias_info->all, r->in.level, &entries_read, r->out.buffer); done: if (!cli) { return werr; } if (is_valid_policy_hnd(&alias_handle)) { rpccli_samr_Close(pipe_cli, ctx, &alias_handle); } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
WERROR NetShareEnum_r(struct libnetapi_ctx *ctx, struct NetShareEnum *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; struct srvsvc_NetShareInfoCtr info_ctr; struct srvsvc_NetShareCtr0 ctr0; struct srvsvc_NetShareCtr1 ctr1; struct srvsvc_NetShareCtr2 ctr2; uint32_t i; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: case 2: break; case 502: case 503: return WERR_NOT_SUPPORTED; default: return WERR_UNKNOWN_LEVEL; } ZERO_STRUCT(info_ctr); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } info_ctr.level = r->in.level; switch (r->in.level) { case 0: ZERO_STRUCT(ctr0); info_ctr.ctr.ctr0 = &ctr0; break; case 1: ZERO_STRUCT(ctr1); info_ctr.ctr.ctr1 = &ctr1; break; case 2: ZERO_STRUCT(ctr2); info_ctr.ctr.ctr2 = &ctr2; break; } status = rpccli_srvsvc_NetShareEnumAll(pipe_cli, ctx, r->in.server_name, &info_ctr, r->in.prefmaxlen, r->out.total_entries, r->out.resume_handle, &werr); if (NT_STATUS_IS_ERR(status)) { goto done; } for (i=0; i < info_ctr.ctr.ctr1->count; i++) { union srvsvc_NetShareInfo _i; switch (r->in.level) { case 0: _i.info0 = &info_ctr.ctr.ctr0->array[i]; break; case 1: _i.info1 = &info_ctr.ctr.ctr1->array[i]; break; case 2: _i.info2 = &info_ctr.ctr.ctr2->array[i]; break; } status = map_srvsvc_share_info_to_SHARE_INFO_buffer(ctx, r->in.level, &_i, r->out.buffer, r->out.entries_read); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); } } done: return werr; }
WERROR NetLocalGroupEnum_r(struct libnetapi_ctx *ctx, struct NetLocalGroupEnum *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status, result; WERROR werr; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; uint32_t entries_read = 0; union samr_DomainInfo *domain_info = NULL; union samr_DomainInfo *builtin_info = NULL; struct samr_SamArray *domain_sam_array = NULL; struct samr_SamArray *builtin_sam_array = NULL; int i; struct dcerpc_binding_handle *b = NULL; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: break; default: return WERR_UNKNOWN_LEVEL; } if (r->out.total_entries) { *r->out.total_entries = 0; } if (r->out.entries_read) { *r->out.entries_read = 0; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(), &builtin_handle, 2, &builtin_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } if (r->out.total_entries) { *r->out.total_entries += builtin_info->general.num_aliases; } status = dcerpc_samr_QueryDomainInfo(b, talloc_tos(), &domain_handle, 2, &domain_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } if (r->out.total_entries) { *r->out.total_entries += domain_info->general.num_aliases; } status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(), &builtin_handle, r->in.resume_handle, &builtin_sam_array, r->in.prefmaxlen, &entries_read, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } for (i=0; i<builtin_sam_array->count; i++) { union samr_AliasInfo *alias_info = NULL; if (r->in.level == 1) { status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli, &builtin_handle, builtin_sam_array->entries[i].idx, SAMR_ALIAS_ACCESS_LOOKUP_INFO, ALIASINFOALL, &alias_info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } werr = map_alias_info_to_buffer(ctx, builtin_sam_array->entries[i].name.string, alias_info ? &alias_info->all : NULL, r->in.level, r->out.entries_read, r->out.buffer); } status = dcerpc_samr_EnumDomainAliases(b, talloc_tos(), &domain_handle, r->in.resume_handle, &domain_sam_array, r->in.prefmaxlen, &entries_read, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } for (i=0; i<domain_sam_array->count; i++) { union samr_AliasInfo *alias_info = NULL; if (r->in.level == 1) { status = libnetapi_samr_open_alias_queryinfo(ctx, pipe_cli, &domain_handle, domain_sam_array->entries[i].idx, SAMR_ALIAS_ACCESS_LOOKUP_INFO, ALIASINFOALL, &alias_info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } werr = map_alias_info_to_buffer(ctx, domain_sam_array->entries[i].name.string, alias_info ? &alias_info->all : NULL, r->in.level, r->out.entries_read, r->out.buffer); } done: if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
WERROR NetLocalGroupSetInfo_r(struct libnetapi_ctx *ctx, struct NetLocalGroupSetInfo *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status, result; WERROR werr; struct lsa_String lsa_account_name; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; enum samr_AliasInfoEnum alias_level = 0; union samr_AliasInfo *alias_info = NULL; struct dcerpc_binding_handle *b = NULL; if (!r->in.group_name) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 1: case 1002: break; default: return WERR_UNKNOWN_LEVEL; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } init_lsa_String(&lsa_account_name, r->in.group_name); status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &builtin_handle, r->in.group_name, SAMR_ALIAS_ACCESS_SET_INFO, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); } if (NT_STATUS_IS_OK(status)) { goto set_alias; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &domain_handle, r->in.group_name, SAMR_ALIAS_ACCESS_SET_INFO, &alias_handle); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); } set_alias: werr = map_buffer_to_alias_info(ctx, r->in.level, r->in.buffer, &alias_level, &alias_info); if (!W_ERROR_IS_OK(werr)) { goto done; } status = dcerpc_samr_SetAliasInfo(b, talloc_tos(), &alias_handle, alias_level, alias_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } werr = WERR_OK; done: if (is_valid_policy_hnd(&alias_handle)) { dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result); } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
WERROR NetLocalGroupDel_r(struct libnetapi_ctx *ctx, struct NetLocalGroupDel *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status, result; WERROR werr; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; struct dcerpc_binding_handle *b = NULL; if (!r->in.group_name) { return WERR_INVALID_PARAM; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &builtin_handle, r->in.group_name, SEC_STD_DELETE, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); } if (NT_STATUS_IS_OK(status)) { goto delete_alias; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, SAMR_DOMAIN_ACCESS_CREATE_ALIAS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &domain_handle, r->in.group_name, SEC_STD_DELETE, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); } if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } delete_alias: status = dcerpc_samr_DeleteDomAlias(b, talloc_tos(), &alias_handle, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } ZERO_STRUCT(alias_handle); werr = WERR_OK; done: if (is_valid_policy_hnd(&alias_handle)) { dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result); } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
WERROR NetLocalGroupAdd_r(struct libnetapi_ctx *ctx, struct NetLocalGroupAdd *r) { struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status, result; WERROR werr; struct lsa_String lsa_account_name; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; uint32_t rid; struct dcerpc_binding_handle *b = NULL; struct LOCALGROUP_INFO_0 *info0 = NULL; struct LOCALGROUP_INFO_1 *info1 = NULL; const char *alias_name = NULL; if (!r->in.buffer) { return WERR_INVALID_PARAM; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); switch (r->in.level) { case 0: info0 = (struct LOCALGROUP_INFO_0 *)r->in.buffer; alias_name = info0->lgrpi0_name; break; case 1: info1 = (struct LOCALGROUP_INFO_1 *)r->in.buffer; alias_name = info1->lgrpi1_name; break; default: werr = WERR_UNKNOWN_LEVEL; goto done; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &builtin_handle, alias_name, SAMR_ALIAS_ACCESS_LOOKUP_INFO, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); } if (NT_STATUS_IS_OK(status)) { werr = WERR_ALIAS_EXISTS; goto done; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, SAMR_DOMAIN_ACCESS_CREATE_ALIAS | SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } init_lsa_String(&lsa_account_name, alias_name); status = dcerpc_samr_CreateDomAlias(b, talloc_tos(), &domain_handle, &lsa_account_name, SEC_STD_DELETE | SAMR_ALIAS_ACCESS_SET_INFO, &alias_handle, &rid, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } if (r->in.level == 1 && info1->lgrpi1_comment) { union samr_AliasInfo alias_info; init_lsa_String(&alias_info.description, info1->lgrpi1_comment); status = dcerpc_samr_SetAliasInfo(b, talloc_tos(), &alias_handle, ALIASINFODESCRIPTION, &alias_info, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } } werr = WERR_OK; done: if (is_valid_policy_hnd(&alias_handle)) { dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result); } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx, struct NetLocalGroupAddMembers *add, struct NetLocalGroupDelMembers *del, struct NetLocalGroupSetMembers *set) { struct NetLocalGroupAddMembers *r = NULL; struct rpc_pipe_client *pipe_cli = NULL; struct rpc_pipe_client *lsa_pipe = NULL; NTSTATUS status, result; WERROR werr; struct lsa_String lsa_account_name; struct policy_handle connect_handle, domain_handle, builtin_handle, alias_handle; struct dom_sid2 *domain_sid = NULL; struct dom_sid *member_sids = NULL; int i = 0, k = 0; struct LOCALGROUP_MEMBERS_INFO_0 *info0 = NULL; struct LOCALGROUP_MEMBERS_INFO_3 *info3 = NULL; struct dom_sid *add_sids = NULL; struct dom_sid *del_sids = NULL; uint32_t num_add_sids = 0; uint32_t num_del_sids = 0; struct dcerpc_binding_handle *b = NULL; if ((!add && !del && !set) || (add && del && set)) { return WERR_INVALID_PARAM; } if (add) { r = add; } if (del) { r = (struct NetLocalGroupAddMembers *)del; } if (set) { r = (struct NetLocalGroupAddMembers *)set; } if (!r->in.group_name) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 0: case 3: break; default: return WERR_UNKNOWN_LEVEL; } if (r->in.total_entries == 0 || !r->in.buffer) { return WERR_INVALID_PARAM; } ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(alias_handle); member_sids = talloc_zero_array(ctx, struct dom_sid, r->in.total_entries); W_ERROR_HAVE_NO_MEMORY(member_sids); switch (r->in.level) { case 0: info0 = (struct LOCALGROUP_MEMBERS_INFO_0 *)r->in.buffer; for (i=0; i < r->in.total_entries; i++) { sid_copy(&member_sids[i], (struct dom_sid *)info0[i].lgrmi0_sid); } break; case 3: info3 = (struct LOCALGROUP_MEMBERS_INFO_3 *)r->in.buffer; break; default: break; } if (r->in.level == 3) { werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_lsarpc, &lsa_pipe); if (!W_ERROR_IS_OK(werr)) { goto done; } for (i=0; i < r->in.total_entries; i++) { status = libnetapi_lsa_lookup_names3(ctx, lsa_pipe, info3[i].lgrmi3_domainandname, &member_sids[i]); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } TALLOC_FREE(lsa_pipe); } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_samr, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } b = pipe_cli->binding_handle; werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, SAMR_ACCESS_LOOKUP_DOMAIN | SAMR_ACCESS_ENUM_DOMAINS, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &builtin_handle); if (!W_ERROR_IS_OK(werr)) { goto done; } init_lsa_String(&lsa_account_name, r->in.group_name); status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &builtin_handle, r->in.group_name, SAMR_ALIAS_ACCESS_ADD_MEMBER | SAMR_ALIAS_ACCESS_REMOVE_MEMBER | SAMR_ALIAS_ACCESS_GET_MEMBERS | SAMR_ALIAS_ACCESS_LOOKUP_INFO, &alias_handle); if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); } if (NT_STATUS_IS_OK(status)) { goto modify_membership; } werr = libnetapi_samr_open_domain(ctx, pipe_cli, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_LOOKUP_DOMAIN, SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, &connect_handle, &domain_handle, &domain_sid); if (!W_ERROR_IS_OK(werr)) { goto done; } status = libnetapi_samr_lookup_and_open_alias(ctx, pipe_cli, &domain_handle, r->in.group_name, SAMR_ALIAS_ACCESS_ADD_MEMBER | SAMR_ALIAS_ACCESS_REMOVE_MEMBER | SAMR_ALIAS_ACCESS_GET_MEMBERS | SAMR_ALIAS_ACCESS_LOOKUP_INFO, &alias_handle); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); } modify_membership: if (add) { for (i=0; i < r->in.total_entries; i++) { status = add_sid_to_array_unique(ctx, &member_sids[i], &add_sids, &num_add_sids); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } } if (del) { for (i=0; i < r->in.total_entries; i++) { status = add_sid_to_array_unique(ctx, &member_sids[i], &del_sids, &num_del_sids); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } } if (set) { struct lsa_SidArray current_sids; status = dcerpc_samr_GetMembersInAlias(b, talloc_tos(), &alias_handle, ¤t_sids, &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } /* add list */ for (i=0; i < r->in.total_entries; i++) { bool already_member = false; for (k=0; k < current_sids.num_sids; k++) { if (dom_sid_equal(&member_sids[i], current_sids.sids[k].sid)) { already_member = true; break; } } if (!already_member) { status = add_sid_to_array_unique(ctx, &member_sids[i], &add_sids, &num_add_sids); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } } /* del list */ for (k=0; k < current_sids.num_sids; k++) { bool keep_member = false; for (i=0; i < r->in.total_entries; i++) { if (dom_sid_equal(&member_sids[i], current_sids.sids[k].sid)) { keep_member = true; break; } } if (!keep_member) { status = add_sid_to_array_unique(ctx, current_sids.sids[k].sid, &del_sids, &num_del_sids); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } } } /* add list */ for (i=0; i < num_add_sids; i++) { status = dcerpc_samr_AddAliasMember(b, talloc_tos(), &alias_handle, &add_sids[i], &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } } /* del list */ for (i=0; i < num_del_sids; i++) { status = dcerpc_samr_DeleteAliasMember(b, talloc_tos(), &alias_handle, &del_sids[i], &result); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } if (!NT_STATUS_IS_OK(result)) { werr = ntstatus_to_werror(result); goto done; } } werr = WERR_OK; done: if (b && is_valid_policy_hnd(&alias_handle)) { dcerpc_samr_Close(b, talloc_tos(), &alias_handle, &result); } if (ctx->disable_policy_handle_cache) { libnetapi_samr_close_domain_handle(ctx, &domain_handle); libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); libnetapi_samr_close_connect_handle(ctx, &connect_handle); } return werr; }
WERROR NetFileEnum_r(struct libnetapi_ctx *ctx, struct NetFileEnum *r) { WERROR werr; NTSTATUS status; struct rpc_pipe_client *pipe_cli = NULL; struct srvsvc_NetFileInfoCtr info_ctr; struct srvsvc_NetFileCtr2 ctr2; struct srvsvc_NetFileCtr3 ctr3; uint32_t num_entries = 0; uint32_t i; if (!r->out.buffer) { return WERR_INVALID_PARAM; } switch (r->in.level) { case 2: case 3: break; default: return WERR_UNKNOWN_LEVEL; } werr = libnetapi_open_pipe(ctx, r->in.server_name, &ndr_table_srvsvc.syntax_id, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } ZERO_STRUCT(info_ctr); info_ctr.level = r->in.level; switch (r->in.level) { case 2: ZERO_STRUCT(ctr2); info_ctr.ctr.ctr2 = &ctr2; break; case 3: ZERO_STRUCT(ctr3); info_ctr.ctr.ctr3 = &ctr3; break; } status = rpccli_srvsvc_NetFileEnum(pipe_cli, talloc_tos(), r->in.server_name, r->in.base_path, r->in.user_name, &info_ctr, r->in.prefmaxlen, r->out.total_entries, r->out.resume_handle, &werr); if (NT_STATUS_IS_ERR(status)) { goto done; } for (i=0; i < info_ctr.ctr.ctr2->count; i++) { union srvsvc_NetFileInfo _i; switch (r->in.level) { case 2: _i.info2 = &info_ctr.ctr.ctr2->array[i]; break; case 3: _i.info3 = &info_ctr.ctr.ctr3->array[i]; break; } status = map_srvsvc_FileInfo_to_FILE_INFO_buffer(ctx, r->in.level, &_i, r->out.buffer, &num_entries); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } } if (r->out.entries_read) { *r->out.entries_read = num_entries; } if (r->out.total_entries) { *r->out.total_entries = num_entries; } done: return werr; }