diff options
author | bubulle <bubulle@alioth.debian.org> | 2008-11-01 11:09:46 +0000 |
---|---|---|
committer | bubulle <bubulle@alioth.debian.org> | 2008-11-01 11:09:46 +0000 |
commit | a2b71a0141763c20552bb45eeb4cb78c4b513118 (patch) | |
tree | 85b64d98387145ea4e00c1b529e1820542a979a3 /source/lib/netapi/user.c | |
parent | 2203bd59918d6d70515f9dad601cb5c0ef098092 (diff) | |
download | samba-a2b71a0141763c20552bb45eeb4cb78c4b513118.tar.gz |
Revert the merge of 3.3.0~pre2 in upstream branch
git-svn-id: svn://svn.debian.org/svn/pkg-samba/branches/samba/upstream@2200 fc4039ab-9d04-0410-8cac-899223bdd6b0
Diffstat (limited to 'source/lib/netapi/user.c')
-rw-r--r-- | source/lib/netapi/user.c | 3176 |
1 files changed, 382 insertions, 2794 deletions
diff --git a/source/lib/netapi/user.c b/source/lib/netapi/user.c index 7d0c47f331..05a051067a 100644 --- a/source/lib/netapi/user.c +++ b/source/lib/netapi/user.c @@ -27,283 +27,102 @@ /**************************************************************** ****************************************************************/ -static void convert_USER_INFO_X_to_samr_user_info21(struct USER_INFO_X *infoX, - struct samr_UserInfo21 *info21) +static void convert_USER_INFO_1_to_samr_user_info25(struct USER_INFO_1 *info1, + DATA_BLOB *user_session_key, + struct samr_UserInfo25 *info25) { - uint32_t fields_present = 0; + uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS; struct samr_LogonHours zero_logon_hours; struct lsa_BinaryString zero_parameters; + uint32_t acct_flags = 0; NTTIME password_age; - ZERO_STRUCTP(info21); + ZERO_STRUCTP(info25); ZERO_STRUCT(zero_logon_hours); ZERO_STRUCT(zero_parameters); - if (infoX->usriX_flags) { - fields_present |= SAMR_FIELD_ACCT_FLAGS; - } - if (infoX->usriX_name) { - fields_present |= SAMR_FIELD_ACCOUNT_NAME; + if (info1->usri1_name) { + fields_present |= SAMR_FIELD_FULL_NAME; } - if (infoX->usriX_password) { + if (info1->usri1_password) { fields_present |= SAMR_FIELD_PASSWORD; } - if (infoX->usriX_flags) { + if (info1->usri1_flags) { fields_present |= SAMR_FIELD_ACCT_FLAGS; } - if (infoX->usriX_name) { + if (info1->usri1_name) { fields_present |= SAMR_FIELD_FULL_NAME; } - if (infoX->usriX_home_dir) { + if (info1->usri1_home_dir) { fields_present |= SAMR_FIELD_HOME_DIRECTORY; } - if (infoX->usriX_script_path) { + if (info1->usri1_script_path) { fields_present |= SAMR_FIELD_LOGON_SCRIPT; } - if (infoX->usriX_comment) { + if (info1->usri1_comment) { fields_present |= SAMR_FIELD_DESCRIPTION; } - if (infoX->usriX_password_age) { + if (info1->usri1_password_age) { fields_present |= SAMR_FIELD_FORCE_PWD_CHANGE; } - if (infoX->usriX_full_name) { - fields_present |= SAMR_FIELD_FULL_NAME; - } - if (infoX->usriX_usr_comment) { - fields_present |= SAMR_FIELD_COMMENT; - } - if (infoX->usriX_profile) { - fields_present |= SAMR_FIELD_PROFILE_PATH; - } - if (infoX->usriX_home_dir_drive) { - fields_present |= SAMR_FIELD_HOME_DRIVE; - } - if (infoX->usriX_primary_group_id) { - fields_present |= SAMR_FIELD_PRIMARY_GID; - } - if (infoX->usriX_country_code) { - fields_present |= SAMR_FIELD_COUNTRY_CODE; - } - if (infoX->usriX_workstations) { - fields_present |= SAMR_FIELD_WORKSTATIONS; - } - unix_to_nt_time_abs(&password_age, infoX->usriX_password_age); + acct_flags |= info1->usri1_flags | ACB_NORMAL; - /* TODO: infoX->usriX_priv */ - init_samr_user_info21(info21, + unix_to_nt_time_abs(&password_age, info1->usri1_password_age); + + /* TODO: info1->usri1_priv */ + init_samr_user_info21(&info25->info, 0, 0, 0, 0, 0, password_age, - infoX->usriX_name, - infoX->usriX_full_name, - infoX->usriX_home_dir, - infoX->usriX_home_dir_drive, - infoX->usriX_script_path, - infoX->usriX_profile, - infoX->usriX_comment, - infoX->usriX_workstations, - infoX->usriX_usr_comment, + NULL, + info1->usri1_name, + info1->usri1_home_dir, + NULL, + info1->usri1_script_path, + NULL, + info1->usri1_comment, + NULL, + NULL, &zero_parameters, 0, - infoX->usriX_primary_group_id, - infoX->usriX_flags, + 0, + acct_flags, fields_present, zero_logon_hours, 0, 0, - infoX->usriX_country_code, + 0, 0, 0, 0, 0); -} -/**************************************************************** -****************************************************************/ + if (info1->usri1_password) { + uchar pwbuf[532]; + struct MD5Context ctx; + uint8_t confounder[16]; + DATA_BLOB confounded_session_key = data_blob(NULL, 16); -static NTSTATUS construct_USER_INFO_X(uint32_t level, - uint8_t *buffer, - struct USER_INFO_X *uX) -{ - struct USER_INFO_0 *u0 = NULL; - struct USER_INFO_1 *u1 = NULL; - struct USER_INFO_2 *u2 = NULL; - struct USER_INFO_1003 *u1003 = NULL; - struct USER_INFO_1006 *u1006 = NULL; - struct USER_INFO_1007 *u1007 = NULL; - struct USER_INFO_1009 *u1009 = NULL; - struct USER_INFO_1011 *u1011 = NULL; - struct USER_INFO_1012 *u1012 = NULL; - struct USER_INFO_1014 *u1014 = NULL; - struct USER_INFO_1024 *u1024 = NULL; - struct USER_INFO_1051 *u1051 = NULL; - struct USER_INFO_1052 *u1052 = NULL; - struct USER_INFO_1053 *u1053 = NULL; - - if (!buffer || !uX) { - return NT_STATUS_INVALID_PARAMETER; - } - - ZERO_STRUCTP(uX); + encode_pw_buffer(pwbuf, info1->usri1_password, STR_UNICODE); - switch (level) { - case 0: - u0 = (struct USER_INFO_0 *)buffer; - uX->usriX_name = u0->usri0_name; - break; - case 1: - u1 = (struct USER_INFO_1 *)buffer; - uX->usriX_name = u1->usri1_name; - uX->usriX_password = u1->usri1_password; - uX->usriX_password_age = u1->usri1_password_age; - uX->usriX_priv = u1->usri1_priv; - uX->usriX_home_dir = u1->usri1_home_dir; - uX->usriX_comment = u1->usri1_comment; - uX->usriX_flags = u1->usri1_flags; - uX->usriX_script_path = u1->usri1_script_path; - break; - case 2: - u2 = (struct USER_INFO_2 *)buffer; - uX->usriX_name = u2->usri2_name; - uX->usriX_password = u2->usri2_password; - uX->usriX_password_age = u2->usri2_password_age; - uX->usriX_priv = u2->usri2_priv; - uX->usriX_home_dir = u2->usri2_home_dir; - uX->usriX_comment = u2->usri2_comment; - uX->usriX_flags = u2->usri2_flags; - uX->usriX_script_path = u2->usri2_script_path; - uX->usriX_auth_flags = u2->usri2_auth_flags; - uX->usriX_full_name = u2->usri2_full_name; - uX->usriX_usr_comment = u2->usri2_usr_comment; - uX->usriX_parms = u2->usri2_parms; - uX->usriX_workstations = u2->usri2_workstations; - uX->usriX_last_logon = u2->usri2_last_logon; - uX->usriX_last_logoff = u2->usri2_last_logoff; - uX->usriX_acct_expires = u2->usri2_acct_expires; - uX->usriX_max_storage = u2->usri2_max_storage; - uX->usriX_units_per_week= u2->usri2_units_per_week; - uX->usriX_logon_hours = u2->usri2_logon_hours; - uX->usriX_bad_pw_count = u2->usri2_bad_pw_count; - uX->usriX_num_logons = u2->usri2_num_logons; - uX->usriX_logon_server = u2->usri2_logon_server; - uX->usriX_country_code = u2->usri2_country_code; - uX->usriX_code_page = u2->usri2_code_page; - break; - case 1003: - u1003 = (struct USER_INFO_1003 *)buffer; - uX->usriX_password = u1003->usri1003_password; - break; - case 1006: - u1006 = (struct USER_INFO_1006 *)buffer; - uX->usriX_home_dir = u1006->usri1006_home_dir; - break; - case 1007: - u1007 = (struct USER_INFO_1007 *)buffer; - uX->usriX_comment = u1007->usri1007_comment; - break; - case 1009: - u1009 = (struct USER_INFO_1009 *)buffer; - uX->usriX_script_path = u1009->usri1009_script_path; - break; - case 1011: - u1011 = (struct USER_INFO_1011 *)buffer; - uX->usriX_full_name = u1011->usri1011_full_name; - break; - case 1012: - u1012 = (struct USER_INFO_1012 *)buffer; - uX->usriX_usr_comment = u1012->usri1012_usr_comment; - break; - case 1014: - u1014 = (struct USER_INFO_1014 *)buffer; - uX->usriX_workstations = u1014->usri1014_workstations; - break; - case 1024: - u1024 = (struct USER_INFO_1024 *)buffer; - uX->usriX_country_code = u1024->usri1024_country_code; - break; - case 1051: - u1051 = (struct USER_INFO_1051 *)buffer; - uX->usriX_primary_group_id = u1051->usri1051_primary_group_id; - break; - case 1052: - u1052 = (struct USER_INFO_1052 *)buffer; - uX->usriX_profile = u1052->usri1052_profile; - break; - case 1053: - u1053 = (struct USER_INFO_1053 *)buffer; - uX->usriX_home_dir_drive = u1053->usri1053_home_dir_drive; - break; - case 3: - case 4: - default: - return NT_STATUS_INVALID_INFO_CLASS; - } + generate_random_buffer((uint8_t *)confounder, 16); - return NT_STATUS_OK; -} + MD5Init(&ctx); + MD5Update(&ctx, confounder, 16); + MD5Update(&ctx, user_session_key->data, + user_session_key->length); + MD5Final(confounded_session_key.data, &ctx); -/**************************************************************** -****************************************************************/ + SamOEMhashBlob(pwbuf, 516, &confounded_session_key); + memcpy(&pwbuf[516], confounder, 16); -static NTSTATUS set_user_info_USER_INFO_X(TALLOC_CTX *ctx, - struct rpc_pipe_client *pipe_cli, - DATA_BLOB *session_key, - struct policy_handle *user_handle, - struct USER_INFO_X *uX) -{ - union samr_UserInfo user_info; - struct samr_UserInfo21 info21; - NTSTATUS status; - - if (!uX) { - return NT_STATUS_INVALID_PARAMETER; - } - - convert_USER_INFO_X_to_samr_user_info21(uX, &info21); - - ZERO_STRUCT(user_info); - - if (uX->usriX_password) { - - user_info.info25.info = info21; - - init_samr_CryptPasswordEx(uX->usriX_password, - session_key, - &user_info.info25.password); - - status = rpccli_samr_SetUserInfo2(pipe_cli, ctx, - user_handle, - 25, - &user_info); - - if (NT_STATUS_EQUAL(status, NT_STATUS(DCERPC_FAULT_INVALID_TAG))) { - - user_info.info23.info = info21; - - init_samr_CryptPassword(uX->usriX_password, - session_key, - &user_info.info23.password); - - status = rpccli_samr_SetUserInfo2(pipe_cli, ctx, - user_handle, - 23, - &user_info); - } - } else { - - user_info.info21 = info21; - - status = rpccli_samr_SetUserInfo(pipe_cli, ctx, - user_handle, - 21, - &user_info); + memcpy(info25->password.data, pwbuf, sizeof(pwbuf)); + data_blob_free(&confounded_session_key); } - - return status; } /**************************************************************** @@ -316,14 +135,21 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; + uint32_t resume_handle = 0; + uint32_t num_entries = 0; POLICY_HND connect_handle, domain_handle, user_handle; - struct lsa_String lsa_account_name; + struct samr_SamArray *sam = NULL; + const char *domain_name = NULL; + struct lsa_String lsa_domain_name, lsa_account_name; struct dom_sid2 *domain_sid = NULL; + struct samr_UserInfo25 info25; union samr_UserInfo *user_info = NULL; struct samr_PwInfo pw_info; uint32_t access_granted = 0; uint32_t rid = 0; - struct USER_INFO_X uX; + bool domain_found = true; + int i; + struct USER_INFO_1 *info1; ZERO_STRUCT(connect_handle); ZERO_STRUCT(domain_handle); @@ -335,6 +161,7 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, switch (r->in.level) { case 1: + info1 = (struct USER_INFO_1 *)r->in.buffer; break; case 2: case 3: @@ -344,34 +171,77 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, goto done; } - werr = libnetapi_open_pipe(ctx, r->in.server_name, - &ndr_table_samr.syntax_id, - &cli, - &pipe_cli); + werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); + werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli); + if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = libnetapi_samr_open_domain(ctx, pipe_cli, + status = rpccli_try_samr_connects(pipe_cli, ctx, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | - SAMR_DOMAIN_ACCESS_CREATE_USER | - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + &connect_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + status = rpccli_samr_EnumDomains(pipe_cli, ctx, + &connect_handle, + &resume_handle, + &sam, + 0xffffffff, + &num_entries); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + for (i=0; i<num_entries; i++) { + + domain_name = sam->entries[i].name.string; + + if (strequal(domain_name, builtin_domain_name())) { + continue; + } + + domain_found = true; + break; + } + + if (!domain_found) { + werr = WERR_NO_SUCH_DOMAIN; + goto done; + } + + init_lsa_String(&lsa_domain_name, domain_name); + + status = rpccli_samr_LookupDomain(pipe_cli, ctx, &connect_handle, - &domain_handle, + &lsa_domain_name, &domain_sid); - if (!W_ERROR_IS_OK(werr)) { + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + status = rpccli_samr_OpenDomain(pipe_cli, ctx, + &connect_handle, + SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | + SAMR_DOMAIN_ACCESS_CREATE_USER | + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + domain_sid, + &domain_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); goto done; } - init_lsa_String(&lsa_account_name, uX.usriX_name); + init_lsa_String(&lsa_account_name, info1->usri1_name); status = rpccli_samr_CreateUser2(pipe_cli, ctx, &domain_handle, @@ -412,12 +282,26 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, goto done; } - uX.usriX_flags |= ACB_NORMAL; + ZERO_STRUCTP(user_info); - status = set_user_info_USER_INFO_X(ctx, pipe_cli, - &cli->user_session_key, - &user_handle, - &uX); + convert_USER_INFO_1_to_samr_user_info25(info1, + &cli->user_session_key, + &info25); + + if (info1->usri1_password) { + user_info->info25 = info25; + status = rpccli_samr_SetUserInfo2(pipe_cli, ctx, + &user_handle, + 25, + user_info); + } else { + user_info->info21 = info25.info; + status = rpccli_samr_SetUserInfo(pipe_cli, ctx, + &user_handle, + 21, + user_info); + + } if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto failed; @@ -438,10 +322,11 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, if (is_valid_policy_hnd(&user_handle)) { rpccli_samr_Close(pipe_cli, ctx, &user_handle); } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); + if (is_valid_policy_hnd(&domain_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &domain_handle); + } + if (is_valid_policy_hnd(&connect_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &connect_handle); } return werr; @@ -453,7 +338,12 @@ WERROR NetUserAdd_r(struct libnetapi_ctx *ctx, WERROR NetUserAdd_l(struct libnetapi_ctx *ctx, struct NetUserAdd *r) { - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserAdd); + /* for now just talk to local RPC server */ + if (!r->in.server_name) { + r->in.server_name = "localhost"; + } + + return NetUserAdd_r(ctx, r); } /**************************************************************** @@ -466,34 +356,88 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; NTSTATUS status; WERROR werr; + uint32_t resume_handle = 0; + uint32_t num_entries = 0; POLICY_HND connect_handle, builtin_handle, domain_handle, user_handle; - struct lsa_String lsa_account_name; + struct samr_SamArray *sam = NULL; + const char *domain_name = NULL; + struct lsa_String lsa_domain_name, lsa_account_name; struct samr_Ids user_rids, name_types; struct dom_sid2 *domain_sid = NULL; struct dom_sid2 user_sid; + bool domain_found = true; + int i; ZERO_STRUCT(connect_handle); ZERO_STRUCT(builtin_handle); ZERO_STRUCT(domain_handle); ZERO_STRUCT(user_handle); - werr = libnetapi_open_pipe(ctx, r->in.server_name, - &ndr_table_samr.syntax_id, - &cli, - &pipe_cli); + werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli); + if (!W_ERROR_IS_OK(werr)) { + goto done; + } + werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = libnetapi_samr_open_domain(ctx, pipe_cli, + status = rpccli_try_samr_connects(pipe_cli, ctx, SAMR_ACCESS_ENUM_DOMAINS | SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + &connect_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + status = rpccli_samr_EnumDomains(pipe_cli, ctx, + &connect_handle, + &resume_handle, + &sam, + 0xffffffff, + &num_entries); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + for (i=0; i<num_entries; i++) { + + domain_name = sam->entries[i].name.string; + + if (strequal(domain_name, builtin_domain_name())) { + continue; + } + + domain_found = true; + break; + } + + if (!domain_found) { + werr = WERR_NO_SUCH_DOMAIN; + goto done; + } + + init_lsa_String(&lsa_domain_name, domain_name); + + status = rpccli_samr_LookupDomain(pipe_cli, ctx, &connect_handle, - &domain_handle, + &lsa_domain_name, &domain_sid); - if (!W_ERROR_IS_OK(werr)) { + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + status = rpccli_samr_OpenDomain(pipe_cli, ctx, + &connect_handle, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + domain_sid, + &domain_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); goto done; } @@ -557,11 +501,14 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx, if (is_valid_policy_hnd(&user_handle)) { rpccli_samr_Close(pipe_cli, ctx, &user_handle); } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_builtin_handle(ctx, &builtin_handle); - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); + if (is_valid_policy_hnd(&builtin_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &builtin_handle); + } + if (is_valid_policy_hnd(&domain_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &domain_handle); + } + if (is_valid_policy_hnd(&connect_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &connect_handle); } return werr; @@ -573,576 +520,46 @@ WERROR NetUserDel_r(struct libnetapi_ctx *ctx, WERROR NetUserDel_l(struct libnetapi_ctx *ctx, struct NetUserDel *r) { - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserDel); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct policy_handle *builtin_handle, - const char *user_name, - const struct dom_sid *domain_sid, - uint32_t rid, - uint32_t level, - struct samr_UserInfo21 **info21, - struct sec_desc_buf **sec_desc, - uint32_t *auth_flag_p) -{ - NTSTATUS status; - - struct policy_handle user_handle; - union samr_UserInfo *user_info = NULL; - struct samr_RidWithAttributeArray *rid_array = NULL; - uint32_t access_mask = SEC_STD_READ_CONTROL | - SAMR_USER_ACCESS_GET_ATTRIBUTES | - SAMR_USER_ACCESS_GET_NAME_ETC; - - ZERO_STRUCT(user_handle); - - switch (level) { - case 0: - break; - case 1: - access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO | - SAMR_USER_ACCESS_GET_GROUPS; - break; - case 2: - case 3: - case 4: - case 11: - access_mask |= SAMR_USER_ACCESS_GET_LOGONINFO | - SAMR_USER_ACCESS_GET_GROUPS | - SAMR_USER_ACCESS_GET_LOCALE; - break; - case 10: - case 20: - case 23: - break; - default: - return NT_STATUS_INVALID_LEVEL; - } - - if (level == 0) { - return NT_STATUS_OK; + /* for now just talk to local RPC server */ + if (!r->in.server_name) { + r->in.server_name = "localhost"; } - status = rpccli_samr_OpenUser(pipe_cli, mem_ctx, - domain_handle, - access_mask, - rid, - &user_handle); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpccli_samr_QueryUserInfo(pipe_cli, mem_ctx, - &user_handle, - 21, - &user_info); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpccli_samr_QuerySecurity(pipe_cli, mem_ctx, - &user_handle, - SECINFO_DACL, - sec_desc); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - if (access_mask & SAMR_USER_ACCESS_GET_GROUPS) { - - struct lsa_SidArray sid_array; - struct samr_Ids alias_rids; - int i; - uint32_t auth_flag = 0; - struct dom_sid sid; - - status = rpccli_samr_GetGroupsForUser(pipe_cli, mem_ctx, - &user_handle, - &rid_array); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - sid_array.num_sids = rid_array->count + 1; - sid_array.sids = talloc_array(mem_ctx, struct lsa_SidPtr, - sid_array.num_sids); - NT_STATUS_HAVE_NO_MEMORY(sid_array.sids); - - for (i=0; i<rid_array->count; i++) { - sid_compose(&sid, domain_sid, rid_array->rids[i].rid); - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid); - NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid); - } - - sid_compose(&sid, domain_sid, rid); - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid); - NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid); - - status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx, - builtin_handle, - &sid_array, - &alias_rids); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - for (i=0; i<alias_rids.count; i++) { - switch (alias_rids.ids[i]) { - case 550: /* Print Operators */ - auth_flag |= AF_OP_PRINT; - break; - case 549: /* Server Operators */ - auth_flag |= AF_OP_SERVER; - break; - case 548: /* Account Operators */ - auth_flag |= AF_OP_ACCOUNTS; - break; - default: - break; - } - } - - if (auth_flag_p) { - *auth_flag_p = auth_flag; - } - } - - *info21 = &user_info->info21; - - done: - if (is_valid_policy_hnd(&user_handle)) { - rpccli_samr_Close(pipe_cli, mem_ctx, &user_handle); - } - - return status; -} - -/**************************************************************** -****************************************************************/ - -static uint32_t samr_rid_to_priv_level(uint32_t rid) -{ - switch (rid) { - case DOMAIN_RID_ADMINISTRATOR: - return USER_PRIV_ADMIN; - case DOMAIN_RID_GUEST: - return USER_PRIV_GUEST; - default: - return USER_PRIV_USER; - } -} - -/**************************************************************** -****************************************************************/ - -static uint32_t samr_acb_flags_to_netapi_flags(uint32_t acb) -{ - uint32_t fl = UF_SCRIPT; /* god knows why */ - - fl |= ads_acb2uf(acb); - - return fl; + return NetUserDel_r(ctx, r); } /**************************************************************** ****************************************************************/ -static NTSTATUS info21_to_USER_INFO_1(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - struct USER_INFO_1 *i) +static WERROR convert_samr_samarray_to_USER_INFO_buffer(TALLOC_CTX *mem_ctx, + struct samr_SamArray *sam_array, + uint32_t level, + uint8_t **buffer) { - ZERO_STRUCTP(i); - i->usri1_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri1_name); - i->usri1_password = NULL; - i->usri1_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change); - i->usri1_priv = samr_rid_to_priv_level(i21->rid); - i->usri1_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string); - i->usri1_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri1_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - i->usri1_script_path = talloc_strdup(mem_ctx, i21->logon_script.string); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_2(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - uint32_t auth_flag, - struct USER_INFO_2 *i) -{ - ZERO_STRUCTP(i); - - i->usri2_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri2_name); - i->usri2_password = NULL; - i->usri2_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change); - i->usri2_priv = samr_rid_to_priv_level(i21->rid); - i->usri2_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string); - i->usri2_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri2_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - i->usri2_script_path = talloc_strdup(mem_ctx, i21->logon_script.string); - i->usri2_auth_flags = auth_flag; - i->usri2_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri2_usr_comment = talloc_strdup(mem_ctx, i21->comment.string); - i->usri2_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2); - i->usri2_workstations = talloc_strdup(mem_ctx, i21->workstations.string); - i->usri2_last_logon = nt_time_to_unix(i21->last_logon); - i->usri2_last_logoff = nt_time_to_unix(i21->last_logoff); - i->usri2_acct_expires = nt_time_to_unix(i21->acct_expiry); - i->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */ - i->usri2_units_per_week = i21->logon_hours.units_per_week; - i->usri2_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21); - i->usri2_bad_pw_count = i21->bad_password_count; - i->usri2_num_logons = i21->logon_count; - i->usri2_logon_server = talloc_strdup(mem_ctx, "\\\\*"); - i->usri2_country_code = i21->country_code; - i->usri2_code_page = i21->code_page; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_3(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - uint32_t auth_flag, - struct USER_INFO_3 *i) -{ - ZERO_STRUCTP(i); - - i->usri3_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri3_name); - i->usri3_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change); - i->usri3_priv = samr_rid_to_priv_level(i21->rid); - i->usri3_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string); - i->usri3_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri3_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - i->usri3_script_path = talloc_strdup(mem_ctx, i21->logon_script.string); - i->usri3_auth_flags = auth_flag; - i->usri3_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri3_usr_comment = talloc_strdup(mem_ctx, i21->comment.string); - i->usri3_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2); - i->usri3_workstations = talloc_strdup(mem_ctx, i21->workstations.string); - i->usri3_last_logon = nt_time_to_unix(i21->last_logon); - i->usri3_last_logoff = nt_time_to_unix(i21->last_logoff); - i->usri3_acct_expires = nt_time_to_unix(i21->acct_expiry); - i->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */ - i->usri3_units_per_week = i21->logon_hours.units_per_week; - i->usri3_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21); - i->usri3_bad_pw_count = i21->bad_password_count; - i->usri3_num_logons = i21->logon_count; - i->usri3_logon_server = talloc_strdup(mem_ctx, "\\\\*"); - i->usri3_country_code = i21->country_code; - i->usri3_code_page = i21->code_page; - i->usri3_user_id = i21->rid; - i->usri3_primary_group_id = i21->primary_gid; - i->usri3_profile = talloc_strdup(mem_ctx, i21->profile_path.string); - i->usri3_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string); - i->usri3_password_expired = i21->password_expired; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - uint32_t auth_flag, - struct dom_sid *domain_sid, - struct USER_INFO_4 *i) -{ - struct dom_sid sid; - - ZERO_STRUCTP(i); - - i->usri4_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri4_name); - i->usri4_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change); - i->usri4_password = NULL; - i->usri4_priv = samr_rid_to_priv_level(i21->rid); - i->usri4_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string); - i->usri4_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri4_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - i->usri4_script_path = talloc_strdup(mem_ctx, i21->logon_script.string); - i->usri4_auth_flags = auth_flag; - i->usri4_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri4_usr_comment = talloc_strdup(mem_ctx, i21->comment.string); - i->usri4_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2); - i->usri4_workstations = talloc_strdup(mem_ctx, i21->workstations.string); - i->usri4_last_logon = nt_time_to_unix(i21->last_logon); - i->usri4_last_logoff = nt_time_to_unix(i21->last_logoff); - i->usri4_acct_expires = nt_time_to_unix(i21->acct_expiry); - i->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */ - i->usri4_units_per_week = i21->logon_hours.units_per_week; - i->usri4_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21); - i->usri4_bad_pw_count = i21->bad_password_count; - i->usri4_num_logons = i21->logon_count; - i->usri4_logon_server = talloc_strdup(mem_ctx, "\\\\*"); - i->usri4_country_code = i21->country_code; - i->usri4_code_page = i21->code_page; - if (!sid_compose(&sid, domain_sid, i21->rid)) { - return NT_STATUS_NO_MEMORY; - } - i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); - i->usri4_primary_group_id = i21->primary_gid; - i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string); - i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string); - i->usri4_password_expired = i21->password_expired; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_10(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - struct USER_INFO_10 *i) -{ - ZERO_STRUCTP(i); - - i->usri10_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri10_name); - i->usri10_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri10_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri10_usr_comment = talloc_strdup(mem_ctx, i21->comment.string); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_11(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - uint32_t auth_flag, - struct USER_INFO_11 *i) -{ - ZERO_STRUCTP(i); - - i->usri11_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri11_name); - i->usri11_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri11_usr_comment = talloc_strdup(mem_ctx, i21->comment.string); - i->usri11_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri11_priv = samr_rid_to_priv_level(i21->rid); - i->usri11_auth_flags = auth_flag; - i->usri11_password_age = time(NULL) - nt_time_to_unix(i21->last_password_change); - i->usri11_home_dir = talloc_strdup(mem_ctx, i21->home_directory.string); - i->usri11_parms = talloc_strndup(mem_ctx, (const char *)i21->parameters.array, i21->parameters.size/2); - i->usri11_last_logon = nt_time_to_unix(i21->last_logon); - i->usri11_last_logoff = nt_time_to_unix(i21->last_logoff); - i->usri11_bad_pw_count = i21->bad_password_count; - i->usri11_num_logons = i21->logon_count; - i->usri11_logon_server = talloc_strdup(mem_ctx, "\\\\*"); - i->usri11_country_code = i21->country_code; - i->usri11_workstations = talloc_strdup(mem_ctx, i21->workstations.string); - i->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; /* FIXME */ - i->usri11_units_per_week = i21->logon_hours.units_per_week; - i->usri11_logon_hours = (uint8_t *)talloc_memdup(mem_ctx, i21->logon_hours.bits, 21); - i->usri11_code_page = i21->code_page; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_20(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - struct USER_INFO_20 *i) -{ - ZERO_STRUCTP(i); - - i->usri20_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri20_name); - i->usri20_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri20_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri20_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - i->usri20_user_id = i21->rid; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx, - const struct samr_UserInfo21 *i21, - struct dom_sid *domain_sid, - struct USER_INFO_23 *i) -{ - struct dom_sid sid; - - ZERO_STRUCTP(i); - - i->usri23_name = talloc_strdup(mem_ctx, i21->account_name.string); - NT_STATUS_HAVE_NO_MEMORY(i->usri23_name); - i->usri23_comment = talloc_strdup(mem_ctx, i21->description.string); - i->usri23_full_name = talloc_strdup(mem_ctx, i21->full_name.string); - i->usri23_flags = samr_acb_flags_to_netapi_flags(i21->acct_flags); - if (!sid_compose(&sid, domain_sid, i21->rid)) { - return NT_STATUS_NO_MEMORY; - } - i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct dom_sid *domain_sid, - struct policy_handle *domain_handle, - struct policy_handle *builtin_handle, - const char *user_name, - uint32_t rid, - uint32_t level, - uint8_t **buffer, - uint32_t *num_entries) -{ - NTSTATUS status; - - struct samr_UserInfo21 *info21 = NULL; - struct sec_desc_buf *sec_desc = NULL; - uint32_t auth_flag = 0; - - struct USER_INFO_0 info0; - struct USER_INFO_1 info1; - struct USER_INFO_2 info2; - struct USER_INFO_3 info3; - struct USER_INFO_4 info4; - struct USER_INFO_10 info10; - struct USER_INFO_11 info11; - struct USER_INFO_20 info20; - struct USER_INFO_23 info23; - - switch (level) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 10: - case 11: - case 20: - case 23: - break; - default: - return NT_STATUS_INVALID_LEVEL; - } - - if (level == 0) { - info0.usri0_name = talloc_strdup(mem_ctx, user_name); - NT_STATUS_HAVE_NO_MEMORY(info0.usri0_name); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_0, info0, - (struct USER_INFO_0 **)buffer, num_entries); - - return NT_STATUS_OK; - } - - status = libnetapi_samr_lookup_user(mem_ctx, pipe_cli, - domain_handle, - builtin_handle, - user_name, - domain_sid, - rid, - level, - &info21, - &sec_desc, - &auth_flag); - - if (!NT_STATUS_IS_OK(status)) { - goto done; - } + struct USER_INFO_0 *info0 = NULL; + int i; switch (level) { case 0: - /* already returned above */ - break; - case 1: - status = info21_to_USER_INFO_1(mem_ctx, info21, &info1); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_1, info1, - (struct USER_INFO_1 **)buffer, num_entries); - - break; - case 2: - status = info21_to_USER_INFO_2(mem_ctx, info21, auth_flag, &info2); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_2, info2, - (struct USER_INFO_2 **)buffer, num_entries); - - break; - case 3: - status = info21_to_USER_INFO_3(mem_ctx, info21, auth_flag, &info3); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_3, info3, - (struct USER_INFO_3 **)buffer, num_entries); - - break; - case 4: - status = info21_to_USER_INFO_4(mem_ctx, info21, auth_flag, domain_sid, &info4); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_4, info4, - (struct USER_INFO_4 **)buffer, num_entries); - - break; - case 10: - status = info21_to_USER_INFO_10(mem_ctx, info21, &info10); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_10, info10, - (struct USER_INFO_10 **)buffer, num_entries); - - break; - case 11: - status = info21_to_USER_INFO_11(mem_ctx, info21, auth_flag, &info11); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_11, info11, - (struct USER_INFO_11 **)buffer, num_entries); - - break; - case 20: - status = info21_to_USER_INFO_20(mem_ctx, info21, &info20); - NT_STATUS_NOT_OK_RETURN(status); - - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_20, info20, - (struct USER_INFO_20 **)buffer, num_entries); - - break; - case 23: - status = info21_to_USER_INFO_23(mem_ctx, info21, domain_sid, &info23); - NT_STATUS_NOT_OK_RETURN(status); + info0 = TALLOC_ZERO_ARRAY(mem_ctx, struct USER_INFO_0, + sam_array->count); + W_ERROR_HAVE_NO_MEMORY(info0); + + for (i=0; i<sam_array->count; i++) { + info0[i].usri0_name = talloc_strdup(mem_ctx, + sam_array->entries[i].name.string); + W_ERROR_HAVE_NO_MEMORY(info0[i].usri0_name); + } - ADD_TO_ARRAY(mem_ctx, struct USER_INFO_23, info23, - (struct USER_INFO_23 **)buffer, num_entries); + *buffer = (uint8_t *)talloc_memdup(mem_ctx, info0, + sizeof(struct USER_INFO_0) * sam_array->count); + W_ERROR_HAVE_NO_MEMORY(*buffer); break; default: - return NT_STATUS_INVALID_LEVEL; + return WERR_NOT_SUPPORTED; } - done: - return status; + return WERR_OK; } /**************************************************************** @@ -1155,137 +572,133 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx, struct rpc_pipe_client *pipe_cli = NULL; struct policy_handle connect_handle; struct dom_sid2 *domain_sid = NULL; - struct policy_handle domain_handle, builtin_handle; + struct policy_handle domain_handle; struct samr_SamArray *sam = NULL; - uint32_t filter = ACB_NORMAL; + uint32_t num_entries = 0; int i; - uint32_t entries_read = 0; + const char *domain_name = NULL; + bool domain_found = true; + uint32_t dom_resume_handle = 0; + struct lsa_String lsa_domain_name; - NTSTATUS status = NT_STATUS_OK; + NTSTATUS status; WERROR werr; ZERO_STRUCT(connect_handle); ZERO_STRUCT(domain_handle); - ZERO_STRUCT(builtin_handle); - - if (!r->out.buffer) { - return WERR_INVALID_PARAM; - } - - *r->out.buffer = NULL; - *r->out.entries_read = 0; switch (r->in.level) { case 0: + break; case 1: case 2: case 3: - case 4: case 10: case 11: case 20: case 23: - break; default: - return WERR_UNKNOWN_LEVEL; + return WERR_NOT_SUPPORTED; } - werr = libnetapi_open_pipe(ctx, r->in.server_name, - &ndr_table_samr.syntax_id, - &cli, - &pipe_cli); + werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, - &connect_handle, - &builtin_handle); + werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = libnetapi_samr_open_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | - SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + status = rpccli_try_samr_connects(pipe_cli, ctx, + SAMR_ACCESS_OPEN_DOMAIN | + SAMR_ACCESS_ENUM_DOMAINS, + &connect_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + status = rpccli_samr_EnumDomains(pipe_cli, ctx, + &connect_handle, + &dom_resume_handle, + &sam, + 0xffffffff, + &num_entries); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; + } + + for (i=0; i<num_entries; i++) { + + domain_name = sam->entries[i].name.string; + + if (strequal(domain_name, builtin_domain_name())) { + continue; + } + + domain_found = true; + break; + } + + if (!domain_found) { + werr = WERR_NO_SUCH_DOMAIN; + goto done; + } + + init_lsa_String(&lsa_domain_name, domain_name); + + status = rpccli_samr_LookupDomain(pipe_cli, ctx, &connect_handle, - &domain_handle, + &lsa_domain_name, &domain_sid); - if (!W_ERROR_IS_OK(werr)) { + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); goto done; } - switch (r->in.filter) { - case FILTER_NORMAL_ACCOUNT: - filter = ACB_NORMAL; - break; - case FILTER_TEMP_DUPLICATE_ACCOUNT: - filter = ACB_TEMPDUP; - break; - case FILTER_INTERDOMAIN_TRUST_ACCOUNT: - filter = ACB_DOMTRUST; - break; - case FILTER_WORKSTATION_TRUST_ACCOUNT: - filter = ACB_WSTRUST; - break; - case FILTER_SERVER_TRUST_ACCOUNT: - filter = ACB_SVRTRUST; - break; - default: - break; + status = rpccli_samr_OpenDomain(pipe_cli, + ctx, + &connect_handle, + SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + domain_sid, + &domain_handle); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); + goto done; } status = rpccli_samr_EnumDomainUsers(pipe_cli, ctx, &domain_handle, r->in.resume_handle, - filter, + r->in.filter, &sam, r->in.prefmaxlen, - &entries_read); - werr = ntstatus_to_werror(status); - if (NT_STATUS_IS_ERR(status)) { + r->out.entries_read); + if (!NT_STATUS_IS_OK(status)) { + werr = ntstatus_to_werror(status); goto done; } - for (i=0; i < sam->count; i++) { - - status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli, - domain_sid, - &domain_handle, - &builtin_handle, - sam->entries[i].name.string, - sam->entries[i].idx, - r->in.level, - r->out.buffer, - r->out.entries_read); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - } + werr = convert_samr_samarray_to_USER_INFO_buffer(ctx, sam, + r->in.level, + r->out.buffer); done: if (!cli) { return werr; } - /* if last query */ - if (NT_STATUS_IS_OK(status) || - NT_STATUS_IS_ERR(status)) { - - 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); - } + if (is_valid_policy_hnd(&domain_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &domain_handle); + } + if (is_valid_policy_hnd(&connect_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &connect_handle); } return werr; @@ -1297,7 +710,7 @@ WERROR NetUserEnum_r(struct libnetapi_ctx *ctx, WERROR NetUserEnum_l(struct libnetapi_ctx *ctx, struct NetUserEnum *r) { - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserEnum); + return WERR_NOT_SUPPORTED; } /**************************************************************** @@ -1432,11 +845,11 @@ static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx, - union samr_DispInfo *info, - uint32_t level, - uint32_t *entries_read, - void **buffer) +WERROR convert_samr_dispinfo_to_NET_DISPLAY(TALLOC_CTX *mem_ctx, + union samr_DispInfo *info, + uint32_t level, + uint32_t *entries_read, + void **buffer) { switch (level) { case 1: @@ -1473,1968 +886,143 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx, struct dom_sid2 *domain_sid = NULL; struct policy_handle domain_handle; union samr_DispInfo info; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; + int i; + const char *domain_name = NULL; + bool domain_found = true; + uint32_t dom_resume_handle = 0; + struct lsa_String lsa_domain_name; uint32_t total_size = 0; uint32_t returned_size = 0; - NTSTATUS status = NT_STATUS_OK; - WERROR werr; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - switch (r->in.level) { - case 1: - case 2: - case 3: - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - 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 = rpccli_samr_QueryDisplayInfo2(pipe_cli, - ctx, - &domain_handle, - r->in.level, - r->in.idx, - r->in.entries_requested, - r->in.prefmaxlen, - &total_size, - &returned_size, - &info); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, - r->in.level, - r->out.entries_read, - r->out.buffer); - done: - if (!cli) { - return werr; - } - - /* if last query */ - if (NT_STATUS_IS_OK(status) || - NT_STATUS_IS_ERR(status)) { - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - } - - return werr; - -} - -/**************************************************************** -****************************************************************/ - - -WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx, - struct NetQueryDisplayInformation *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetQueryDisplayInformation); -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserChangePassword_r(struct libnetapi_ctx *ctx, - struct NetUserChangePassword *r) -{ - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserChangePassword_l(struct libnetapi_ctx *ctx, - struct NetUserChangePassword *r) -{ - return WERR_NOT_SUPPORTED; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetInfo_r(struct libnetapi_ctx *ctx, - struct NetUserGetInfo *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, user_handle; - struct lsa_String lsa_account_name; - struct dom_sid2 *domain_sid = NULL; - struct samr_Ids user_rids, name_types; - uint32_t num_entries = 0; - ZERO_STRUCT(connect_handle); ZERO_STRUCT(domain_handle); - ZERO_STRUCT(builtin_handle); - ZERO_STRUCT(user_handle); - - if (!r->out.buffer) { - return WERR_INVALID_PARAM; - } switch (r->in.level) { - case 0: case 1: case 2: case 3: - case 4: - case 10: - case 11: - case 20: - case 23: - break; - default: - werr = WERR_UNKNOWN_LEVEL; - goto done; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, - &connect_handle, - &domain_handle, - &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, - &connect_handle, - &builtin_handle); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - init_lsa_String(&lsa_account_name, r->in.user_name); - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - 1, - &lsa_account_name, - &user_rids, - &name_types); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = libnetapi_samr_lookup_user_map_USER_INFO(ctx, pipe_cli, - domain_sid, - &domain_handle, - &builtin_handle, - r->in.user_name, - user_rids.ids[0], - r->in.level, - r->out.buffer, - &num_entries); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - done: - if (!cli) { - return werr; - } - - if (is_valid_policy_hnd(&user_handle)) { - rpccli_samr_Close(pipe_cli, ctx, &user_handle); - } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - - return werr; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetInfo_l(struct libnetapi_ctx *ctx, - struct NetUserGetInfo *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetInfo); -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserSetInfo_r(struct libnetapi_ctx *ctx, - struct NetUserSetInfo *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, user_handle; - struct lsa_String lsa_account_name; - struct dom_sid2 *domain_sid = NULL; - struct samr_Ids user_rids, name_types; - uint32_t user_mask = 0; - - struct USER_INFO_X uX; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - ZERO_STRUCT(builtin_handle); - ZERO_STRUCT(user_handle); - - if (!r->in.buffer) { - return WERR_INVALID_PARAM; - } - - switch (r->in.level) { - case 0: - case 1003: - user_mask = SAMR_USER_ACCESS_SET_PASSWORD; - break; - case 1006: - case 1007: - case 1009: - case 1011: - case 1014: - case 1052: - case 1053: - user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES; - break; - case 1012: - case 1024: - user_mask = SAMR_USER_ACCESS_SET_LOC_COM; - case 1051: - user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES | - SAMR_USER_ACCESS_GET_GROUPS; - break; - case 1: - case 2: - case 3: - case 4: - case 21: - case 22: - case 1005: - case 1008: - case 1010: - case 1017: - case 1020: - werr = WERR_NOT_SUPPORTED; - goto done; - default: - werr = WERR_UNKNOWN_LEVEL; - goto done; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, - &connect_handle, - &domain_handle, - &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, - &connect_handle, - &builtin_handle); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - init_lsa_String(&lsa_account_name, r->in.user_name); - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - 1, - &lsa_account_name, - &user_rids, - &name_types); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = rpccli_samr_OpenUser(pipe_cli, ctx, - &domain_handle, - user_mask, - user_rids.ids[0], - &user_handle); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = construct_USER_INFO_X(r->in.level, r->in.buffer, &uX); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = set_user_info_USER_INFO_X(ctx, pipe_cli, - &cli->user_session_key, - &user_handle, - &uX); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - werr = WERR_OK; - - done: - if (!cli) { - return werr; - } - - if (is_valid_policy_hnd(&user_handle)) { - rpccli_samr_Close(pipe_cli, ctx, &user_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 NetUserSetInfo_l(struct libnetapi_ctx *ctx, - struct NetUserSetInfo *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetInfo); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct samr_DomInfo1 *info1, - struct samr_DomInfo3 *info3, - struct samr_DomInfo5 *info5, - struct samr_DomInfo6 *info6, - struct samr_DomInfo7 *info7, - struct samr_DomInfo12 *info12) -{ - NTSTATUS status; - union samr_DomainInfo *dom_info = NULL; - - if (info1) { - status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 1, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info1 = dom_info->info1; - } - - if (info3) { - status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 3, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info3 = dom_info->info3; - } - - if (info5) { - status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 5, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info5 = dom_info->info5; - } - - if (info6) { - status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 6, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info6 = dom_info->info6; - } - - if (info7) { - status = rpccli_samr_QueryDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 7, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info7 = dom_info->info7; - } - - if (info12) { - status = rpccli_samr_QueryDomainInfo2(pipe_cli, mem_ctx, - domain_handle, - 12, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - - *info12 = dom_info->info12; - } - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_0(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_0 *info0) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info1; - struct samr_DomInfo3 dom_info3; - - ZERO_STRUCTP(info0); - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info1, - &dom_info3, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - info0->usrmod0_min_passwd_len = - dom_info1.min_password_length; - info0->usrmod0_max_passwd_age = - nt_time_to_unix_abs((NTTIME *)&dom_info1.max_password_age); - info0->usrmod0_min_passwd_age = - nt_time_to_unix_abs((NTTIME *)&dom_info1.min_password_age); - info0->usrmod0_password_hist_len = - dom_info1.password_history_length; - - info0->usrmod0_force_logoff = - nt_time_to_unix_abs(&dom_info3.force_logoff_time); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_1(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1 *info1) -{ - NTSTATUS status; - struct samr_DomInfo6 dom_info6; - struct samr_DomInfo7 dom_info7; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - NULL, - NULL, - &dom_info6, - &dom_info7, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - info1->usrmod1_primary = - talloc_strdup(mem_ctx, dom_info6.primary.string); - - info1->usrmod1_role = dom_info7.role; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct dom_sid *domain_sid, - struct USER_MODALS_INFO_2 *info2) -{ - NTSTATUS status; - struct samr_DomInfo5 dom_info5; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - NULL, - &dom_info5, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - info2->usrmod2_domain_name = - talloc_strdup(mem_ctx, dom_info5.domain_name.string); - info2->usrmod2_domain_id = - (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid); - - NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name); - NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_3(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_3 *info3) -{ - NTSTATUS status; - struct samr_DomInfo12 dom_info12; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - NULL, - NULL, - NULL, - NULL, - &dom_info12); - NT_STATUS_NOT_OK_RETURN(status); - - info3->usrmod3_lockout_duration = - nt_time_to_unix_abs(&dom_info12.lockout_duration); - info3->usrmod3_lockout_observation_window = - nt_time_to_unix_abs(&dom_info12.lockout_window); - info3->usrmod3_lockout_threshold = - dom_info12.lockout_threshold; - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS query_USER_MODALS_INFO_to_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - uint32_t level, - struct policy_handle *domain_handle, - struct dom_sid *domain_sid, - uint8_t **buffer) -{ - NTSTATUS status; - - struct USER_MODALS_INFO_0 info0; - struct USER_MODALS_INFO_1 info1; - struct USER_MODALS_INFO_2 info2; - struct USER_MODALS_INFO_3 info3; - - if (!buffer) { - return ERROR_INSUFFICIENT_BUFFER; - } - - switch (level) { - case 0: - status = query_USER_MODALS_INFO_0(mem_ctx, - pipe_cli, - domain_handle, - &info0); - NT_STATUS_NOT_OK_RETURN(status); - - *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info0, - sizeof(info0)); - break; - - case 1: - status = query_USER_MODALS_INFO_1(mem_ctx, - pipe_cli, - domain_handle, - &info1); - NT_STATUS_NOT_OK_RETURN(status); - - *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info1, - sizeof(info1)); - break; - case 2: - status = query_USER_MODALS_INFO_2(mem_ctx, - pipe_cli, - domain_handle, - domain_sid, - &info2); - NT_STATUS_NOT_OK_RETURN(status); - - *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info2, - sizeof(info2)); - break; - case 3: - status = query_USER_MODALS_INFO_3(mem_ctx, - pipe_cli, - domain_handle, - &info3); - NT_STATUS_NOT_OK_RETURN(status); - - *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3, - sizeof(info3)); - break; - default: - break; - } - - NT_STATUS_HAVE_NO_MEMORY(*buffer); - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserModalsGet_r(struct libnetapi_ctx *ctx, - struct NetUserModalsGet *r) -{ - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - NTSTATUS status; - WERROR werr; - - struct policy_handle connect_handle, domain_handle; - struct dom_sid2 *domain_sid = NULL; - uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - if (!r->out.buffer) { - return WERR_INVALID_PARAM; - } - - switch (r->in.level) { - case 0: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2; - break; - case 1: - case 2: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2; - break; - case 3: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1; - break; - default: - werr = WERR_UNKNOWN_LEVEL; - goto done; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - access_mask, - &connect_handle, - &domain_handle, - &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - /* 0: 1 + 3 */ - /* 1: 6 + 7 */ - /* 2: 5 */ - /* 3: 12 (DomainInfo2) */ - - status = query_USER_MODALS_INFO_to_buffer(ctx, - pipe_cli, - r->in.level, - &domain_handle, - domain_sid, - r->out.buffer); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - done: - if (!cli) { - return werr; - } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - - return werr; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserModalsGet_l(struct libnetapi_ctx *ctx, - struct NetUserModalsGet *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsGet); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_rpc(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct samr_DomInfo1 *info1, - struct samr_DomInfo3 *info3, - struct samr_DomInfo12 *info12) -{ - NTSTATUS status; - union samr_DomainInfo dom_info; - - if (info1) { - - ZERO_STRUCT(dom_info); - - dom_info.info1 = *info1; - - status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 1, - &dom_info); - NT_STATUS_NOT_OK_RETURN(status); - } - - if (info3) { - - ZERO_STRUCT(dom_info); - - dom_info.info3 = *info3; - - status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 3, - &dom_info); - - NT_STATUS_NOT_OK_RETURN(status); - } - - if (info12) { - - ZERO_STRUCT(dom_info); - - dom_info.info12 = *info12; - - status = rpccli_samr_SetDomainInfo(pipe_cli, mem_ctx, - domain_handle, - 12, - &dom_info); - - NT_STATUS_NOT_OK_RETURN(status); - } - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_0_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_0 *info0) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info_1; - struct samr_DomInfo3 dom_info_3; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - &dom_info_3, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - dom_info_1.min_password_length = - info0->usrmod0_min_passwd_len; - dom_info_1.password_history_length = - info0->usrmod0_password_hist_len; - - unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age, - info0->usrmod0_max_passwd_age); - unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age, - info0->usrmod0_min_passwd_age); - - unix_to_nt_time_abs(&dom_info_3.force_logoff_time, - info0->usrmod0_force_logoff); - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - &dom_info_3, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_3_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_3 *info3) -{ - NTSTATUS status; - struct samr_DomInfo12 dom_info_12; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - NULL, - NULL, - NULL, - NULL, - &dom_info_12); - NT_STATUS_NOT_OK_RETURN(status); - - unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_duration, - info3->usrmod3_lockout_duration); - unix_to_nt_time_abs((NTTIME *)&dom_info_12.lockout_window, - info3->usrmod3_lockout_observation_window); - dom_info_12.lockout_threshold = info3->usrmod3_lockout_threshold; - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - NULL, - &dom_info_12); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_1001_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1001 *info1001) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info_1; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - dom_info_1.min_password_length = - info1001->usrmod1001_min_passwd_len; - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_1002_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1002 *info1002) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info_1; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - unix_to_nt_time_abs((NTTIME *)&dom_info_1.max_password_age, - info1002->usrmod1002_max_passwd_age); - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_1003_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1003 *info1003) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info_1; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - unix_to_nt_time_abs((NTTIME *)&dom_info_1.min_password_age, - info1003->usrmod1003_min_passwd_age); - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_1004_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1004 *info1004) -{ - NTSTATUS status; - struct samr_DomInfo3 dom_info_3; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - &dom_info_3, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - unix_to_nt_time_abs(&dom_info_3.force_logoff_time, - info1004->usrmod1004_force_logoff); - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - NULL, - &dom_info_3, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_1005_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - struct policy_handle *domain_handle, - struct USER_MODALS_INFO_1005 *info1005) -{ - NTSTATUS status; - struct samr_DomInfo1 dom_info_1; - - status = query_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL, - NULL, - NULL, - NULL); - NT_STATUS_NOT_OK_RETURN(status); - - dom_info_1.password_history_length = - info1005->usrmod1005_password_hist_len; - - return set_USER_MODALS_INFO_rpc(mem_ctx, - pipe_cli, - domain_handle, - &dom_info_1, - NULL, - NULL); -} - -/**************************************************************** -****************************************************************/ - -static NTSTATUS set_USER_MODALS_INFO_buffer(TALLOC_CTX *mem_ctx, - struct rpc_pipe_client *pipe_cli, - uint32_t level, - struct policy_handle *domain_handle, - struct dom_sid *domain_sid, - uint8_t *buffer) -{ - struct USER_MODALS_INFO_0 *info0; - struct USER_MODALS_INFO_3 *info3; - struct USER_MODALS_INFO_1001 *info1001; - struct USER_MODALS_INFO_1002 *info1002; - struct USER_MODALS_INFO_1003 *info1003; - struct USER_MODALS_INFO_1004 *info1004; - struct USER_MODALS_INFO_1005 *info1005; - - if (!buffer) { - return ERROR_INSUFFICIENT_BUFFER; - } - - switch (level) { - case 0: - info0 = (struct USER_MODALS_INFO_0 *)buffer; - return set_USER_MODALS_INFO_0_buffer(mem_ctx, - pipe_cli, - domain_handle, - info0); - case 3: - info3 = (struct USER_MODALS_INFO_3 *)buffer; - return set_USER_MODALS_INFO_3_buffer(mem_ctx, - pipe_cli, - domain_handle, - info3); - case 1001: - info1001 = (struct USER_MODALS_INFO_1001 *)buffer; - return set_USER_MODALS_INFO_1001_buffer(mem_ctx, - pipe_cli, - domain_handle, - info1001); - case 1002: - info1002 = (struct USER_MODALS_INFO_1002 *)buffer; - return set_USER_MODALS_INFO_1002_buffer(mem_ctx, - pipe_cli, - domain_handle, - info1002); - case 1003: - info1003 = (struct USER_MODALS_INFO_1003 *)buffer; - return set_USER_MODALS_INFO_1003_buffer(mem_ctx, - pipe_cli, - domain_handle, - info1003); - case 1004: - info1004 = (struct USER_MODALS_INFO_1004 *)buffer; - return set_USER_MODALS_INFO_1004_buffer(mem_ctx, - pipe_cli, - domain_handle, - info1004); - case 1005: - info1005 = (struct USER_MODALS_INFO_1005 *)buffer; - return set_USER_MODALS_INFO_1005_buffer(mem_ctx, - pipe_cli, - domain_handle, - info1005); - - default: - break; - } - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserModalsSet_r(struct libnetapi_ctx *ctx, - struct NetUserModalsSet *r) -{ - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - NTSTATUS status; - WERROR werr; - - struct policy_handle connect_handle, domain_handle; - struct dom_sid2 *domain_sid = NULL; - uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - if (!r->in.buffer) { - return WERR_INVALID_PARAM; - } - - switch (r->in.level) { - case 0: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | - SAMR_DOMAIN_ACCESS_SET_INFO_1 | - SAMR_DOMAIN_ACCESS_SET_INFO_2; - break; - case 3: - case 1001: - case 1002: - case 1003: - case 1005: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 | - SAMR_DOMAIN_ACCESS_SET_INFO_1; - break; - case 1004: - access_mask |= SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 | - SAMR_DOMAIN_ACCESS_SET_INFO_2; - break; - case 1: - case 2: - case 1006: - case 1007: - werr = WERR_NOT_SUPPORTED; - break; - default: - werr = WERR_UNKNOWN_LEVEL; - goto done; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - access_mask, - &connect_handle, - &domain_handle, - &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - status = set_USER_MODALS_INFO_buffer(ctx, - pipe_cli, - r->in.level, - &domain_handle, - domain_sid, - r->in.buffer); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - done: - if (!cli) { - return werr; - } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - - return werr; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserModalsSet_l(struct libnetapi_ctx *ctx, - struct NetUserModalsSet *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserModalsSet); -} - -/**************************************************************** -****************************************************************/ - -NTSTATUS add_GROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx, - uint32_t level, - const char *group_name, - uint32_t attributes, - uint8_t **buffer, - uint32_t *num_entries) -{ - struct GROUP_USERS_INFO_0 u0; - struct GROUP_USERS_INFO_1 u1; - - switch (level) { - case 0: - u0.grui0_name = talloc_strdup(mem_ctx, group_name); - NT_STATUS_HAVE_NO_MEMORY(u0.grui0_name); - - ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_0, u0, - (struct GROUP_USERS_INFO_0 **)buffer, num_entries); - break; - case 1: - u1.grui1_name = talloc_strdup(mem_ctx, group_name); - NT_STATUS_HAVE_NO_MEMORY(u1.grui1_name); - - u1.grui1_attributes = attributes; - - ADD_TO_ARRAY(mem_ctx, struct GROUP_USERS_INFO_1, u1, - (struct GROUP_USERS_INFO_1 **)buffer, num_entries); - break; - default: - return NT_STATUS_INVALID_INFO_CLASS; - } - - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, - struct NetUserGetGroups *r) -{ - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - struct policy_handle connect_handle, domain_handle, user_handle; - struct lsa_String lsa_account_name; - struct dom_sid2 *domain_sid = NULL; - struct samr_Ids user_rids, name_types; - struct samr_RidWithAttributeArray *rid_array = NULL; - struct lsa_Strings names; - struct samr_Ids types; - uint32_t *rids = NULL; - - int i; - uint32_t entries_read = 0; - - NTSTATUS status = NT_STATUS_OK; - WERROR werr; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - if (!r->out.buffer) { - return WERR_INVALID_PARAM; - } - - *r->out.buffer = NULL; - *r->out.entries_read = 0; - - switch (r->in.level) { - case 0: - case 1: break; default: return WERR_UNKNOWN_LEVEL; } - werr = libnetapi_open_pipe(ctx, r->in.server_name, - &ndr_table_samr.syntax_id, - &cli, - &pipe_cli); + werr = libnetapi_open_ipc_connection(ctx, r->in.server_name, &cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - werr = libnetapi_samr_open_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, - &connect_handle, - &domain_handle, - &domain_sid); + werr = libnetapi_open_pipe(ctx, cli, PI_SAMR, &pipe_cli); if (!W_ERROR_IS_OK(werr)) { goto done; } - init_lsa_String(&lsa_account_name, r->in.user_name); - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - 1, - &lsa_account_name, - &user_rids, - &name_types); + status = rpccli_try_samr_connects(pipe_cli, ctx, + SAMR_ACCESS_OPEN_DOMAIN | + SAMR_ACCESS_ENUM_DOMAINS, + &connect_handle); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } - status = rpccli_samr_OpenUser(pipe_cli, ctx, - &domain_handle, - SAMR_USER_ACCESS_GET_GROUPS, - user_rids.ids[0], - &user_handle); + status = rpccli_samr_EnumDomains(pipe_cli, ctx, + &connect_handle, + &dom_resume_handle, + &sam, + 0xffffffff, + &num_entries); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } - status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx, - &user_handle, - &rid_array); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } + for (i=0; i<num_entries; i++) { - rids = talloc_array(ctx, uint32_t, rid_array->count); - if (!rids) { - werr = WERR_NOMEM; - goto done; - } - - for (i=0; i < rid_array->count; i++) { - rids[i] = rid_array->rids[i].rid; - } - - status = rpccli_samr_LookupRids(pipe_cli, ctx, - &domain_handle, - rid_array->count, - rids, - &names, - &types); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } + domain_name = sam->entries[i].name.string; - for (i=0; i < rid_array->count; i++) { - status = add_GROUP_USERS_INFO_X_buffer(ctx, - r->in.level, - names.names[i].string, - rid_array->rids[i].attributes, - r->out.buffer, - &entries_read); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; + if (strequal(domain_name, builtin_domain_name())) { + continue; } - } - - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } - - done: - if (!cli) { - return werr; - } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - - return werr; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetGroups_l(struct libnetapi_ctx *ctx, - struct NetUserGetGroups *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetGroups); -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserSetGroups_r(struct libnetapi_ctx *ctx, - struct NetUserSetGroups *r) -{ - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - struct policy_handle connect_handle, domain_handle, user_handle, group_handle; - struct lsa_String lsa_account_name; - struct dom_sid2 *domain_sid = NULL; - struct samr_Ids user_rids, name_types; - struct samr_Ids group_rids; - struct samr_RidWithAttributeArray *rid_array = NULL; - struct lsa_String *lsa_names = NULL; - - uint32_t *add_rids = NULL; - uint32_t *del_rids = NULL; - size_t num_add_rids = 0; - size_t num_del_rids = 0; - - uint32_t *member_rids = NULL; - size_t num_member_rids = 0; - - struct GROUP_USERS_INFO_0 *i0 = NULL; - struct GROUP_USERS_INFO_1 *i1 = NULL; - int i, k; - - NTSTATUS status = NT_STATUS_OK; - WERROR werr; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - if (!r->in.buffer) { - return WERR_INVALID_PARAM; + domain_found = true; + break; } - switch (r->in.level) { - case 0: - case 1: - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - werr = libnetapi_open_pipe(ctx, r->in.server_name, - &ndr_table_samr.syntax_id, - &cli, - &pipe_cli); - if (!W_ERROR_IS_OK(werr)) { + if (!domain_found) { + werr = WERR_NO_SUCH_DOMAIN; goto done; } - werr = libnetapi_samr_open_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + init_lsa_String(&lsa_domain_name, domain_name); + + status = rpccli_samr_LookupDomain(pipe_cli, ctx, &connect_handle, - &domain_handle, + &lsa_domain_name, &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - init_lsa_String(&lsa_account_name, r->in.user_name); - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - 1, - &lsa_account_name, - &user_rids, - &name_types); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } - status = rpccli_samr_OpenUser(pipe_cli, ctx, - &domain_handle, - SAMR_USER_ACCESS_GET_GROUPS, - user_rids.ids[0], - &user_handle); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - switch (r->in.level) { - case 0: - i0 = (struct GROUP_USERS_INFO_0 *)r->in.buffer; - break; - case 1: - i1 = (struct GROUP_USERS_INFO_1 *)r->in.buffer; - break; - } - - lsa_names = talloc_array(ctx, struct lsa_String, r->in.num_entries); - if (!lsa_names) { - werr = WERR_NOMEM; - goto done; - } - - for (i=0; i < r->in.num_entries; i++) { - - switch (r->in.level) { - case 0: - init_lsa_String(&lsa_names[i], i0->grui0_name); - i0++; - break; - case 1: - init_lsa_String(&lsa_names[i], i1->grui1_name); - i1++; - break; - } - } - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - r->in.num_entries, - lsa_names, - &group_rids, - &name_types); + status = rpccli_samr_OpenDomain(pipe_cli, + ctx, + &connect_handle, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, + domain_sid, + &domain_handle); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } - member_rids = group_rids.ids; - num_member_rids = group_rids.count; - - status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx, - &user_handle, - &rid_array); + status = rpccli_samr_QueryDisplayInfo2(pipe_cli, + ctx, + &domain_handle, + r->in.level, + r->in.idx, + r->in.entries_requested, + r->in.prefmaxlen, + &total_size, + &returned_size, + &info); if (!NT_STATUS_IS_OK(status)) { werr = ntstatus_to_werror(status); goto done; } - /* add list */ - - for (i=0; i < r->in.num_entries; i++) { - bool already_member = false; - for (k=0; k < rid_array->count; k++) { - if (member_rids[i] == rid_array->rids[k].rid) { - already_member = true; - break; - } - } - if (!already_member) { - if (!add_rid_to_array_unique(ctx, - member_rids[i], - &add_rids, &num_add_rids)) { - werr = WERR_GENERAL_FAILURE; - goto done; - } - } - } - - /* del list */ - - for (k=0; k < rid_array->count; k++) { - bool keep_member = false; - for (i=0; i < r->in.num_entries; i++) { - if (member_rids[i] == rid_array->rids[k].rid) { - keep_member = true; - break; - } - } - if (!keep_member) { - if (!add_rid_to_array_unique(ctx, - rid_array->rids[k].rid, - &del_rids, &num_del_rids)) { - werr = WERR_GENERAL_FAILURE; - goto done; - } - } - } - - /* add list */ - - for (i=0; i < num_add_rids; i++) { - status = rpccli_samr_OpenGroup(pipe_cli, ctx, - &domain_handle, - SAMR_GROUP_ACCESS_ADD_MEMBER, - add_rids[i], - &group_handle); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = rpccli_samr_AddGroupMember(pipe_cli, ctx, - &group_handle, - user_rids.ids[0], - 7 /* ? */); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - if (is_valid_policy_hnd(&group_handle)) { - rpccli_samr_Close(pipe_cli, ctx, &group_handle); - } - } - - /* del list */ - - for (i=0; i < num_del_rids; i++) { - status = rpccli_samr_OpenGroup(pipe_cli, ctx, - &domain_handle, - SAMR_GROUP_ACCESS_REMOVE_MEMBER, - del_rids[i], - &group_handle); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = rpccli_samr_DeleteGroupMember(pipe_cli, ctx, - &group_handle, - user_rids.ids[0]); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - if (is_valid_policy_hnd(&group_handle)) { - rpccli_samr_Close(pipe_cli, ctx, &group_handle); - } - } - - werr = WERR_OK; - + werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, + r->in.level, + r->out.entries_read, + r->out.buffer); done: if (!cli) { return werr; } - if (is_valid_policy_hnd(&group_handle)) { - rpccli_samr_Close(pipe_cli, ctx, &group_handle); + if (is_valid_policy_hnd(&domain_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &domain_handle); } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); + if (is_valid_policy_hnd(&connect_handle)) { + rpccli_samr_Close(pipe_cli, ctx, &connect_handle); } return werr; -} -/**************************************************************** -****************************************************************/ - -WERROR NetUserSetGroups_l(struct libnetapi_ctx *ctx, - struct NetUserSetGroups *r) -{ - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserSetGroups); } /**************************************************************** ****************************************************************/ -static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer(TALLOC_CTX *mem_ctx, - uint32_t level, - const char *group_name, - uint8_t **buffer, - uint32_t *num_entries) -{ - struct LOCALGROUP_USERS_INFO_0 u0; - - switch (level) { - case 0: - u0.lgrui0_name = talloc_strdup(mem_ctx, group_name); - NT_STATUS_HAVE_NO_MEMORY(u0.lgrui0_name); - - ADD_TO_ARRAY(mem_ctx, struct LOCALGROUP_USERS_INFO_0, u0, - (struct LOCALGROUP_USERS_INFO_0 **)buffer, num_entries); - break; - default: - return NT_STATUS_INVALID_INFO_CLASS; - } - return NT_STATUS_OK; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, - struct NetUserGetLocalGroups *r) -{ - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - struct policy_handle connect_handle, domain_handle, user_handle, - builtin_handle; - struct lsa_String lsa_account_name; - struct dom_sid2 *domain_sid = NULL; - struct samr_Ids user_rids, name_types; - struct samr_RidWithAttributeArray *rid_array = NULL; - struct lsa_Strings names; - struct samr_Ids types; - uint32_t *rids = NULL; - size_t num_rids = 0; - struct dom_sid user_sid; - struct lsa_SidArray sid_array; - struct samr_Ids domain_rids; - struct samr_Ids builtin_rids; - - int i; - uint32_t entries_read = 0; - - NTSTATUS status = NT_STATUS_OK; - WERROR werr; - - ZERO_STRUCT(connect_handle); - ZERO_STRUCT(domain_handle); - - if (!r->out.buffer) { - return WERR_INVALID_PARAM; - } - - *r->out.buffer = NULL; - *r->out.entries_read = 0; - - switch (r->in.level) { - case 0: - case 1: - break; - default: - return WERR_UNKNOWN_LEVEL; - } - - 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_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, - &connect_handle, - &domain_handle, - &domain_sid); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - werr = libnetapi_samr_open_builtin_domain(ctx, pipe_cli, - SAMR_ACCESS_ENUM_DOMAINS | - SAMR_ACCESS_OPEN_DOMAIN, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, - &connect_handle, - &builtin_handle); - if (!W_ERROR_IS_OK(werr)) { - goto done; - } - - init_lsa_String(&lsa_account_name, r->in.user_name); - - status = rpccli_samr_LookupNames(pipe_cli, ctx, - &domain_handle, - 1, - &lsa_account_name, - &user_rids, - &name_types); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = rpccli_samr_OpenUser(pipe_cli, ctx, - &domain_handle, - SAMR_USER_ACCESS_GET_GROUPS, - user_rids.ids[0], - &user_handle); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - status = rpccli_samr_GetGroupsForUser(pipe_cli, ctx, - &user_handle, - &rid_array); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - if (!sid_compose(&user_sid, domain_sid, user_rids.ids[0])) { - werr = WERR_NOMEM; - goto done; - } - - sid_array.num_sids = rid_array->count + 1; - sid_array.sids = TALLOC_ARRAY(ctx, struct lsa_SidPtr, sid_array.num_sids); - if (!sid_array.sids) { - werr = WERR_NOMEM; - goto done; - } - - sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid); - if (!sid_array.sids[0].sid) { - werr = WERR_NOMEM; - goto done; - } - - for (i=0; i < rid_array->count; i++) { - struct dom_sid sid; - - if (!sid_compose(&sid, domain_sid, rid_array->rids[i].rid)) { - werr = WERR_NOMEM; - goto done; - } - - sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid); - if (!sid_array.sids[i+1].sid) { - werr = WERR_NOMEM; - goto done; - } - } - - status = rpccli_samr_GetAliasMembership(pipe_cli, ctx, - &domain_handle, - &sid_array, - &domain_rids); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - for (i=0; i < domain_rids.count; i++) { - if (!add_rid_to_array_unique(ctx, domain_rids.ids[i], - &rids, &num_rids)) { - werr = WERR_NOMEM; - goto done; - } - } - - status = rpccli_samr_GetAliasMembership(pipe_cli, ctx, - &builtin_handle, - &sid_array, - &builtin_rids); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - for (i=0; i < builtin_rids.count; i++) { - if (!add_rid_to_array_unique(ctx, builtin_rids.ids[i], - &rids, &num_rids)) { - werr = WERR_NOMEM; - goto done; - } - } - - status = rpccli_samr_LookupRids(pipe_cli, ctx, - &builtin_handle, - num_rids, - rids, - &names, - &types); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - - for (i=0; i < names.count; i++) { - status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx, - r->in.level, - names.names[i].string, - r->out.buffer, - &entries_read); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); - goto done; - } - } - - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } - - done: - if (!cli) { - return werr; - } - - if (ctx->disable_policy_handle_cache) { - libnetapi_samr_close_domain_handle(ctx, &domain_handle); - libnetapi_samr_close_connect_handle(ctx, &connect_handle); - } - - return werr; -} - -/**************************************************************** -****************************************************************/ - -WERROR NetUserGetLocalGroups_l(struct libnetapi_ctx *ctx, - struct NetUserGetLocalGroups *r) +WERROR NetQueryDisplayInformation_l(struct libnetapi_ctx *ctx, + struct NetQueryDisplayInformation *r) { - LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetUserGetLocalGroups); + return WERR_NOT_SUPPORTED; } |