Changeset 745 for trunk/server/source3/winbindd/winbindd_rpc.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/winbindd/winbindd_rpc.c
r596 r745 1 /* 2 Unix SMB/CIFS implementation. 3 4 Winbind rpc backend functions 5 6 Copyright (C) Tim Potter 2000-2001,2003 7 Copyright (C) Andrew Tridgell 2001 8 Copyright (C) Volker Lendecke 2005 9 Copyright (C) Guenther Deschner 2008 (pidl conversion) 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 1 /* 2 * Unix SMB/CIFS implementation. 3 * 4 * Winbind rpc backend functions 5 * 6 * Copyright (c) 2000-2003 Tim Potter 7 * Copyright (c) 2001 Andrew Tridgell 8 * Copyright (c) 2005 Volker Lendecke 9 * Copyright (c) 2008 Guenther Deschner (pidl conversion) 10 * Copyright (c) 2010 Andreas Schneider <asn@samba.org> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. 24 */ 24 25 25 26 #include "includes.h" 26 27 #include "winbindd.h" 27 #include "../librpc/gen_ndr/cli_samr.h" 28 #include "../librpc/gen_ndr/cli_lsa.h" 29 30 #undef DBGC_CLASS 31 #define DBGC_CLASS DBGC_WINBIND 32 33 34 /* Query display info for a domain. This returns enough information plus a 35 bit extra to give an overview of domain users for the User Manager 36 application. */ 37 static NTSTATUS query_user_list(struct winbindd_domain *domain, 38 TALLOC_CTX *mem_ctx, 39 uint32 *num_entries, 40 struct wbint_userinfo **info) 41 { 42 NTSTATUS result; 43 struct policy_handle dom_pol; 44 unsigned int i, start_idx; 45 uint32 loop_count; 46 struct rpc_pipe_client *cli; 47 48 DEBUG(3,("rpc: query_user_list\n")); 49 50 *num_entries = 0; 51 *info = NULL; 52 53 if ( !winbindd_can_contact_domain( domain ) ) { 54 DEBUG(10,("query_user_list: No incoming trust for domain %s\n", 55 domain->name)); 56 return NT_STATUS_OK; 57 } 58 59 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 60 if (!NT_STATUS_IS_OK(result)) 61 return result; 62 63 i = start_idx = 0; 64 loop_count = 0; 28 #include "winbindd_rpc.h" 29 #include "rpc_client/rpc_client.h" 30 #include "librpc/gen_ndr/ndr_samr_c.h" 31 #include "librpc/gen_ndr/ndr_lsa_c.h" 32 #include "rpc_client/cli_samr.h" 33 #include "rpc_client/cli_lsarpc.h" 34 #include "../libcli/security/security.h" 35 36 /* Query display info for a domain */ 37 NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, 38 struct rpc_pipe_client *samr_pipe, 39 struct policy_handle *samr_policy, 40 const struct dom_sid *domain_sid, 41 uint32_t *pnum_info, 42 struct wbint_userinfo **pinfo) 43 { 44 struct wbint_userinfo *info = NULL; 45 uint32_t num_info = 0; 46 uint32_t loop_count = 0; 47 uint32_t start_idx = 0; 48 uint32_t i = 0; 49 NTSTATUS status, result; 50 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 51 52 *pnum_info = 0; 65 53 66 54 do { 67 uint32 num_dom_users, j; 68 uint32 max_entries, max_size; 55 uint32_t j; 56 uint32_t num_dom_users; 57 uint32_t max_entries, max_size; 69 58 uint32_t total_size, returned_size; 70 71 59 union samr_DispInfo disp_info; 72 60 73 /* this next bit is copied from net_user_list_internal() */74 75 get_query_dispinfo_params(loop_count, &max_entries,76 &max_size); 77 78 result = rpccli_samr_QueryDisplayInfo(cli,mem_ctx,79 &dom_pol,80 1, 61 dcerpc_get_query_dispinfo_params(loop_count, 62 &max_entries, 63 &max_size); 64 65 status = dcerpc_samr_QueryDisplayInfo(b, 66 mem_ctx, 67 samr_policy, 68 1, /* level */ 81 69 start_idx, 82 70 max_entries, … … 84 72 &total_size, 85 73 &returned_size, 86 &disp_info); 87 74 &disp_info, 75 &result); 76 if (!NT_STATUS_IS_OK(status)) { 77 return status; 78 } 88 79 if (!NT_STATUS_IS_OK(result)) { 89 90 91 92 } 93 94 num_dom_users = disp_info.info1.count;80 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 81 return result; 82 } 83 } 84 85 /* increment required start query values */ 95 86 start_idx += disp_info.info1.count; 96 87 loop_count++; 97 98 *num_entries += num_dom_users; 99 100 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 101 struct wbint_userinfo, 102 *num_entries); 103 104 if (!(*info)) { 88 num_dom_users = disp_info.info1.count; 89 90 num_info += num_dom_users; 91 92 info = TALLOC_REALLOC_ARRAY(mem_ctx, 93 info, 94 struct wbint_userinfo, 95 num_info); 96 if (info == NULL) { 105 97 return NT_STATUS_NO_MEMORY; 106 98 } 107 99 108 100 for (j = 0; j < num_dom_users; i++, j++) { 109 110 101 uint32_t rid = disp_info.info1.entries[j].rid; 111 112 (*info)[i].acct_name = talloc_strdup(mem_ctx, 113 disp_info.info1.entries[j].account_name.string); 114 (*info)[i].full_name = talloc_strdup(mem_ctx, 115 disp_info.info1.entries[j].full_name.string); 116 (*info)[i].homedir = NULL; 117 (*info)[i].shell = NULL; 118 sid_compose(&(*info)[i].user_sid, &domain->sid, rid); 102 struct samr_DispEntryGeneral *src; 103 struct wbint_userinfo *dst; 104 105 src = &(disp_info.info1.entries[j]); 106 dst = &(info[i]); 107 108 dst->acct_name = talloc_strdup(info, 109 src->account_name.string); 110 if (dst->acct_name == NULL) { 111 return NT_STATUS_NO_MEMORY; 112 } 113 114 dst->full_name = talloc_strdup(info, src->full_name.string); 115 if ((src->full_name.string != NULL) && 116 (dst->full_name == NULL)) 117 { 118 return NT_STATUS_NO_MEMORY; 119 } 120 121 dst->homedir = NULL; 122 dst->shell = NULL; 123 124 sid_compose(&dst->user_sid, domain_sid, rid); 119 125 120 126 /* For the moment we set the primary group for … … 125 131 force group' smb.conf parameter or 126 132 something like that. */ 127 128 sid_compose(&(*info)[i].group_sid, &domain->sid, 129 DOMAIN_GROUP_RID_USERS); 130 } 131 133 sid_compose(&dst->group_sid, domain_sid, 134 DOMAIN_RID_USERS); 135 } 132 136 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 133 137 134 return result; 135 } 136 137 /* list all domain groups */ 138 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 139 TALLOC_CTX *mem_ctx, 140 uint32 *num_entries, 141 struct acct_info **info) 142 { 143 struct policy_handle dom_pol; 144 NTSTATUS status; 145 uint32 start = 0; 146 struct rpc_pipe_client *cli; 147 148 *num_entries = 0; 149 *info = NULL; 150 151 DEBUG(3,("rpc: enum_dom_groups\n")); 152 153 if ( !winbindd_can_contact_domain( domain ) ) { 154 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n", 155 domain->name)); 156 return NT_STATUS_OK; 157 } 158 159 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 160 if (!NT_STATUS_IS_OK(status)) 161 return status; 138 *pnum_info = num_info; 139 *pinfo = info; 140 141 return NT_STATUS_OK; 142 } 143 144 /* List all domain groups */ 145 NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx, 146 struct rpc_pipe_client *samr_pipe, 147 struct policy_handle *samr_policy, 148 uint32_t *pnum_info, 149 struct wb_acct_info **pinfo) 150 { 151 struct wb_acct_info *info = NULL; 152 uint32_t start = 0; 153 uint32_t num_info = 0; 154 NTSTATUS status, result; 155 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 156 157 *pnum_info = 0; 162 158 163 159 do { 164 160 struct samr_SamArray *sam_array = NULL; 165 uint32 count = 0; 166 TALLOC_CTX *mem_ctx2; 167 int g; 168 169 mem_ctx2 = talloc_init("enum_dom_groups[rpc]"); 161 uint32_t count = 0; 162 uint32_t g; 170 163 171 164 /* start is updated by this call. */ 172 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2, 173 &dom_pol, 165 status = dcerpc_samr_EnumDomainGroups(b, 166 mem_ctx, 167 samr_policy, 174 168 &start, 175 169 &sam_array, 176 170 0xFFFF, /* buffer size? */ 177 &count); 178 179 if (!NT_STATUS_IS_OK(status) && 180 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 181 talloc_destroy(mem_ctx2); 182 break; 183 } 184 185 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 186 struct acct_info, 187 (*num_entries) + count); 188 if (! *info) { 189 talloc_destroy(mem_ctx2); 171 &count, 172 &result); 173 if (!NT_STATUS_IS_OK(status)) { 174 return status; 175 } 176 if (!NT_STATUS_IS_OK(result)) { 177 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 178 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n", 179 nt_errstr(result))); 180 return result; 181 } 182 } 183 184 info = TALLOC_REALLOC_ARRAY(mem_ctx, 185 info, 186 struct wb_acct_info, 187 num_info + count); 188 if (info == NULL) { 190 189 return NT_STATUS_NO_MEMORY; 191 190 } 192 191 193 for (g=0; g < count; g++) { 194 195 fstrcpy((*info)[*num_entries + g].acct_name, 192 for (g = 0; g < count; g++) { 193 fstrcpy(info[num_info + g].acct_name, 196 194 sam_array->entries[g].name.string); 197 (*info)[*num_entries + g].rid = sam_array->entries[g].idx; 198 } 199 200 (*num_entries) += count; 201 talloc_destroy(mem_ctx2); 202 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); 203 204 return status; 205 } 206 207 /* List all domain groups */ 208 209 static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 210 TALLOC_CTX *mem_ctx, 211 uint32 *num_entries, 212 struct acct_info **info) 213 { 214 struct policy_handle dom_pol; 215 NTSTATUS result; 216 struct rpc_pipe_client *cli; 217 218 *num_entries = 0; 219 *info = NULL; 220 221 DEBUG(3,("rpc: enum_local_groups\n")); 222 223 if ( !winbindd_can_contact_domain( domain ) ) { 224 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n", 225 domain->name)); 226 return NT_STATUS_OK; 227 } 228 229 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 230 if (!NT_STATUS_IS_OK(result)) 231 return result; 195 196 info[num_info + g].rid = sam_array->entries[g].idx; 197 } 198 199 num_info += count; 200 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 201 202 *pnum_info = num_info; 203 *pinfo = info; 204 205 return NT_STATUS_OK; 206 } 207 208 NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx, 209 struct rpc_pipe_client *samr_pipe, 210 struct policy_handle *samr_policy, 211 uint32_t *pnum_info, 212 struct wb_acct_info **pinfo) 213 { 214 struct wb_acct_info *info = NULL; 215 uint32_t num_info = 0; 216 NTSTATUS status, result; 217 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 218 219 *pnum_info = 0; 232 220 233 221 do { 234 222 struct samr_SamArray *sam_array = NULL; 235 uint32 count = 0, start = *num_entries; 236 TALLOC_CTX *mem_ctx2; 237 int g; 238 239 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]"); 240 241 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2, 242 &dom_pol, 223 uint32_t count = 0; 224 uint32_t start = num_info; 225 uint32_t g; 226 227 status = dcerpc_samr_EnumDomainAliases(b, 228 mem_ctx, 229 samr_policy, 243 230 &start, 244 231 &sam_array, 245 232 0xFFFF, /* buffer size? */ 246 &count); 247 if (!NT_STATUS_IS_OK(result) && 248 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 249 { 250 talloc_destroy(mem_ctx2); 251 return result; 252 } 253 254 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 255 struct acct_info, 256 (*num_entries) + count); 257 if (! *info) { 258 talloc_destroy(mem_ctx2); 259 return NT_STATUS_NO_MEMORY; 260 } 261 262 for (g=0; g < count; g++) { 263 264 fstrcpy((*info)[*num_entries + g].acct_name, 233 &count, 234 &result); 235 if (!NT_STATUS_IS_OK(status)) { 236 return status; 237 } 238 if (!NT_STATUS_IS_OK(result)) { 239 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 240 return result; 241 } 242 } 243 244 info = TALLOC_REALLOC_ARRAY(mem_ctx, 245 info, 246 struct wb_acct_info, 247 num_info + count); 248 if (info == NULL) { 249 return NT_STATUS_NO_MEMORY; 250 } 251 252 for (g = 0; g < count; g++) { 253 fstrcpy(info[num_info + g].acct_name, 265 254 sam_array->entries[g].name.string); 266 (*info)[*num_entries + g].rid = sam_array->entries[g].idx; 267 } 268 269 (*num_entries) += count; 270 talloc_destroy(mem_ctx2); 271 255 info[num_info + g].rid = sam_array->entries[g].idx; 256 } 257 258 num_info += count; 272 259 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 273 260 274 return result; 261 *pnum_info = num_info; 262 *pinfo = info; 263 264 return NT_STATUS_OK; 275 265 } 276 266 277 267 /* convert a single name to a sid in a domain */ 278 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain, 279 TALLOC_CTX *mem_ctx, 280 const char *domain_name, 281 const char *name, 282 uint32_t flags, 283 DOM_SID *sid, 284 enum lsa_SidType *type) 285 { 286 NTSTATUS result; 287 DOM_SID *sids = NULL; 268 NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx, 269 struct rpc_pipe_client *lsa_pipe, 270 struct policy_handle *lsa_policy, 271 const char *domain_name, 272 const char *name, 273 uint32_t flags, 274 struct dom_sid *sid, 275 enum lsa_SidType *type) 276 { 288 277 enum lsa_SidType *types = NULL; 278 struct dom_sid *sids = NULL; 289 279 char *full_name = NULL; 290 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;291 280 char *mapped_name = NULL; 292 293 if (name == NULL || *name=='\0') { 281 NTSTATUS status; 282 283 if (name == NULL || name[0] == '\0') { 294 284 full_name = talloc_asprintf(mem_ctx, "%s", domain_name); 295 } else if (domain_name == NULL || *domain_name== '\0') {285 } else if (domain_name == NULL || domain_name[0] == '\0') { 296 286 full_name = talloc_asprintf(mem_ctx, "%s", name); 297 287 } else { 298 288 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name); 299 289 } 300 if (!full_name) { 301 DEBUG(0, ("talloc_asprintf failed!\n"));290 291 if (full_name == NULL) { 302 292 return NT_STATUS_NO_MEMORY; 303 293 } 304 294 305 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name)); 306 307 name_map_status = normalize_name_unmap(mem_ctx, full_name, 308 &mapped_name); 309 310 /* Reset the full_name pointer if we mapped anytthing */ 311 312 if (NT_STATUS_IS_OK(name_map_status) || 313 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 314 { 295 status = normalize_name_unmap(mem_ctx, full_name, &mapped_name); 296 /* Reset the full_name pointer if we mapped anything */ 297 if (NT_STATUS_IS_OK(status) || 298 NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) { 315 299 full_name = mapped_name; 316 300 } 317 301 318 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", 319 full_name?full_name:"", domain_name )); 320 321 result = winbindd_lookup_names(mem_ctx, domain, 1, 322 (const char **)&full_name, NULL, 323 &sids, &types); 324 if (!NT_STATUS_IS_OK(result)) 325 return result; 326 327 /* Return rid and type if lookup successful */ 302 DEBUG(3,("name_to_sid: %s for domain %s\n", 303 full_name ? full_name : "", domain_name )); 304 305 /* 306 * We don't run into deadlocks here, cause winbind_off() is 307 * called in the main function. 308 */ 309 status = rpccli_lsa_lookup_names(lsa_pipe, 310 mem_ctx, 311 lsa_policy, 312 1, /* num_names */ 313 (const char **) &full_name, 314 NULL, /* domains */ 315 1, /* level */ 316 &sids, 317 &types); 318 if (!NT_STATUS_IS_OK(status)) { 319 DEBUG(2,("name_to_sid: failed to lookup name: %s\n", 320 nt_errstr(status))); 321 return status; 322 } 328 323 329 324 sid_copy(sid, &sids[0]); … … 333 328 } 334 329 335 /* 336 convert a domain SID to a user or group name 337 */ 338 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, 339 TALLOC_CTX *mem_ctx, 340 const DOM_SID *sid, 341 char **domain_name, 342 char **name, 343 enum lsa_SidType *type) 344 { 345 char **domains; 346 char **names; 330 /* Convert a domain SID to a user or group name */ 331 NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx, 332 struct rpc_pipe_client *lsa_pipe, 333 struct policy_handle *lsa_policy, 334 struct winbindd_domain *domain, 335 const struct dom_sid *sid, 336 char **pdomain_name, 337 char **pname, 338 enum lsa_SidType *ptype) 339 { 340 char *mapped_name = NULL; 341 char **domains = NULL; 342 char **names = NULL; 347 343 enum lsa_SidType *types = NULL; 348 NTSTATUS result; 349 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; 350 char *mapped_name = NULL; 351 352 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid), 353 domain->name )); 354 355 result = winbindd_lookup_sids(mem_ctx, 356 domain, 357 1, 358 sid, 359 &domains, 360 &names, 361 &types); 362 if (!NT_STATUS_IS_OK(result)) { 363 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n", 364 nt_errstr(result))); 365 return result; 366 } 367 368 369 *type = (enum lsa_SidType)types[0]; 370 *domain_name = domains[0]; 371 *name = names[0]; 372 373 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); 374 375 name_map_status = normalize_name_map(mem_ctx, domain, *name, 376 &mapped_name); 377 if (NT_STATUS_IS_OK(name_map_status) || 378 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 379 { 380 *name = mapped_name; 381 DEBUG(5,("returning mapped name -- %s\n", *name)); 344 NTSTATUS map_status; 345 NTSTATUS status; 346 347 status = rpccli_lsa_lookup_sids(lsa_pipe, 348 mem_ctx, 349 lsa_policy, 350 1, /* num_sids */ 351 sid, 352 &domains, 353 &names, 354 &types); 355 if (!NT_STATUS_IS_OK(status)) { 356 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n", 357 nt_errstr(status))); 358 return status; 359 } 360 361 *ptype = (enum lsa_SidType) types[0]; 362 363 map_status = normalize_name_map(mem_ctx, 364 domain, 365 *pname, 366 &mapped_name); 367 if (NT_STATUS_IS_OK(map_status) || 368 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) { 369 *pname = talloc_strdup(mem_ctx, mapped_name); 370 DEBUG(5,("returning mapped name -- %s\n", *pname)); 371 } else { 372 *pname = talloc_strdup(mem_ctx, names[0]); 373 } 374 if (*pname == NULL) { 375 return NT_STATUS_NO_MEMORY; 376 } 377 378 *pdomain_name = talloc_strdup(mem_ctx, domains[0]); 379 if (*pdomain_name == NULL) { 380 return NT_STATUS_NO_MEMORY; 382 381 } 383 382 … … 385 384 } 386 385 387 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, 388 TALLOC_CTX *mem_ctx, 389 const DOM_SID *sid, 390 uint32 *rids, 391 size_t num_rids, 392 char **domain_name, 393 char ***names, 394 enum lsa_SidType **types) 395 { 396 char **domains; 397 NTSTATUS result; 398 DOM_SID *sids; 386 /* Convert a bunch of rids to user or group names */ 387 NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx, 388 struct rpc_pipe_client *lsa_pipe, 389 struct policy_handle *lsa_policy, 390 struct winbindd_domain *domain, 391 const struct dom_sid *sid, 392 uint32_t *rids, 393 size_t num_rids, 394 char **pdomain_name, 395 char ***pnames, 396 enum lsa_SidType **ptypes) 397 { 398 enum lsa_SidType *types = NULL; 399 char *domain_name = NULL; 400 char **domains = NULL; 401 char **names = NULL; 402 struct dom_sid *sids; 399 403 size_t i; 400 char **ret_names; 401 402 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name )); 403 404 if (num_rids) { 405 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids); 404 NTSTATUS status; 405 406 if (num_rids > 0) { 407 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids); 406 408 if (sids == NULL) { 407 409 return NT_STATUS_NO_MEMORY; … … 411 413 } 412 414 413 for (i =0; i<num_rids; i++) {415 for (i = 0; i < num_rids; i++) { 414 416 if (!sid_compose(&sids[i], sid, rids[i])) { 415 417 return NT_STATUS_INTERNAL_ERROR; … … 417 419 } 418 420 419 result = winbindd_lookup_sids(mem_ctx, 420 domain, 421 num_rids, 422 sids, 423 &domains, 424 names, 425 types); 426 427 if (!NT_STATUS_IS_OK(result) && 428 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 421 status = rpccli_lsa_lookup_sids(lsa_pipe, 422 mem_ctx, 423 lsa_policy, 424 num_rids, 425 sids, 426 &domains, 427 &names, 428 &types); 429 if (!NT_STATUS_IS_OK(status) && 430 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { 431 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n", 432 nt_errstr(status))); 433 return status; 434 } 435 436 for (i = 0; i < num_rids; i++) { 437 char *mapped_name = NULL; 438 NTSTATUS map_status; 439 440 if (types[i] != SID_NAME_UNKNOWN) { 441 map_status = normalize_name_map(mem_ctx, 442 domain, 443 names[i], 444 &mapped_name); 445 if (NT_STATUS_IS_OK(map_status) || 446 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) { 447 TALLOC_FREE(names[i]); 448 names[i] = talloc_strdup(names, mapped_name); 449 if (names[i] == NULL) { 450 return NT_STATUS_NO_MEMORY; 451 } 452 } 453 454 domain_name = domains[i]; 455 } 456 } 457 458 *pdomain_name = domain_name; 459 *ptypes = types; 460 *pnames = names; 461 462 return NT_STATUS_OK; 463 } 464 465 /* Lookup user information from a rid or username. */ 466 NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx, 467 struct rpc_pipe_client *samr_pipe, 468 struct policy_handle *samr_policy, 469 const struct dom_sid *domain_sid, 470 const struct dom_sid *user_sid, 471 struct wbint_userinfo *user_info) 472 { 473 struct policy_handle user_policy; 474 union samr_UserInfo *info = NULL; 475 uint32_t user_rid; 476 NTSTATUS status, result; 477 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 478 479 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { 480 return NT_STATUS_UNSUCCESSFUL; 481 } 482 483 /* Get user handle */ 484 status = dcerpc_samr_OpenUser(b, 485 mem_ctx, 486 samr_policy, 487 SEC_FLAG_MAXIMUM_ALLOWED, 488 user_rid, 489 &user_policy, 490 &result); 491 if (!NT_STATUS_IS_OK(status)) { 492 return status; 493 } 494 if (!NT_STATUS_IS_OK(result)) { 429 495 return result; 430 496 } 431 497 432 ret_names = *names; 433 for (i=0; i<num_rids; i++) { 434 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; 435 char *mapped_name = NULL; 436 437 if ((*types)[i] != SID_NAME_UNKNOWN) { 438 name_map_status = normalize_name_map(mem_ctx, 439 domain, 440 ret_names[i], 441 &mapped_name); 442 if (NT_STATUS_IS_OK(name_map_status) || 443 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 444 { 445 ret_names[i] = mapped_name; 446 } 447 448 *domain_name = domains[i]; 449 } 450 } 451 452 return result; 453 } 454 455 /* Lookup user information from a rid or username. */ 456 static NTSTATUS query_user(struct winbindd_domain *domain, 457 TALLOC_CTX *mem_ctx, 458 const DOM_SID *user_sid, 459 struct wbint_userinfo *user_info) 460 { 461 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 462 struct policy_handle dom_pol, user_pol; 463 union samr_UserInfo *info = NULL; 464 uint32 user_rid; 465 struct netr_SamInfo3 *user; 466 struct rpc_pipe_client *cli; 467 468 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid))); 469 470 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 471 return NT_STATUS_UNSUCCESSFUL; 498 /* Get user info */ 499 status = dcerpc_samr_QueryUserInfo(b, 500 mem_ctx, 501 &user_policy, 502 0x15, 503 &info, 504 &result); 505 { 506 NTSTATUS _result; 507 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result); 508 } 509 if (!NT_STATUS_IS_OK(status)) { 510 return status; 511 } 512 if (!NT_STATUS_IS_OK(result)) { 513 return result; 514 } 515 516 sid_compose(&user_info->user_sid, domain_sid, user_rid); 517 sid_compose(&user_info->group_sid, domain_sid, 518 info->info21.primary_gid); 519 520 user_info->acct_name = talloc_strdup(user_info, 521 info->info21.account_name.string); 522 if (user_info->acct_name == NULL) { 523 return NT_STATUS_NO_MEMORY; 524 } 525 526 user_info->full_name = talloc_strdup(user_info, 527 info->info21.full_name.string); 528 if ((info->info21.full_name.string != NULL) && 529 (user_info->acct_name == NULL)) 530 { 531 return NT_STATUS_NO_MEMORY; 532 } 472 533 473 534 user_info->homedir = NULL; … … 475 536 user_info->primary_gid = (gid_t)-1; 476 537 477 /* try netsamlogon cache first */ 478 479 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 480 { 481 482 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 483 sid_string_dbg(user_sid))); 484 485 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid); 486 sid_compose(&user_info->group_sid, &domain->sid, 487 user->base.primary_gid); 488 489 user_info->acct_name = talloc_strdup(mem_ctx, 490 user->base.account_name.string); 491 user_info->full_name = talloc_strdup(mem_ctx, 492 user->base.full_name.string); 493 494 TALLOC_FREE(user); 495 496 return NT_STATUS_OK; 497 } 498 499 if ( !winbindd_can_contact_domain( domain ) ) { 500 DEBUG(10,("query_user: No incoming trust for domain %s\n", 501 domain->name)); 502 return NT_STATUS_OK; 503 } 504 505 /* no cache; hit the wire */ 506 507 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 508 if (!NT_STATUS_IS_OK(result)) 509 return result; 538 return NT_STATUS_OK; 539 } 540 541 /* Lookup groups a user is a member of. */ 542 NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx, 543 struct rpc_pipe_client *samr_pipe, 544 struct policy_handle *samr_policy, 545 const struct dom_sid *domain_sid, 546 const struct dom_sid *user_sid, 547 uint32_t *pnum_groups, 548 struct dom_sid **puser_grpsids) 549 { 550 struct policy_handle user_policy; 551 struct samr_RidWithAttributeArray *rid_array = NULL; 552 struct dom_sid *user_grpsids = NULL; 553 uint32_t num_groups = 0, i; 554 uint32_t user_rid; 555 NTSTATUS status, result; 556 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 557 558 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { 559 return NT_STATUS_UNSUCCESSFUL; 560 } 510 561 511 562 /* Get user handle */ 512 result = rpccli_samr_OpenUser(cli, mem_ctx, 513 &dom_pol, 563 status = dcerpc_samr_OpenUser(b, 564 mem_ctx, 565 samr_policy, 514 566 SEC_FLAG_MAXIMUM_ALLOWED, 515 567 user_rid, 516 &user_pol); 517 518 if (!NT_STATUS_IS_OK(result)) 568 &user_policy, 569 &result); 570 if (!NT_STATUS_IS_OK(status)) { 571 return status; 572 } 573 if (!NT_STATUS_IS_OK(result)) { 519 574 return result; 520 521 /* Get user info */ 522 result = rpccli_samr_QueryUserInfo(cli, mem_ctx, 523 &user_pol, 524 0x15, 525 &info); 526 527 rpccli_samr_Close(cli, mem_ctx, &user_pol); 528 529 if (!NT_STATUS_IS_OK(result)) 575 } 576 577 /* Query user rids */ 578 status = dcerpc_samr_GetGroupsForUser(b, 579 mem_ctx, 580 &user_policy, 581 &rid_array, 582 &result); 583 num_groups = rid_array->count; 584 585 { 586 NTSTATUS _result; 587 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result); 588 } 589 590 if (!NT_STATUS_IS_OK(status)) { 591 return status; 592 } 593 if (!NT_STATUS_IS_OK(result) || num_groups == 0) { 530 594 return result; 531 532 sid_compose(&user_info->user_sid, &domain->sid, user_rid); 533 sid_compose(&user_info->group_sid, &domain->sid, 534 info->info21.primary_gid); 535 user_info->acct_name = talloc_strdup(mem_ctx, 536 info->info21.account_name.string); 537 user_info->full_name = talloc_strdup(mem_ctx, 538 info->info21.full_name.string); 539 user_info->homedir = NULL; 540 user_info->shell = NULL; 541 user_info->primary_gid = (gid_t)-1; 595 } 596 597 user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups); 598 if (user_grpsids == NULL) { 599 status = NT_STATUS_NO_MEMORY; 600 return status; 601 } 602 603 for (i = 0; i < num_groups; i++) { 604 sid_compose(&(user_grpsids[i]), domain_sid, 605 rid_array->rids[i].rid); 606 } 607 608 *pnum_groups = num_groups; 609 610 *puser_grpsids = user_grpsids; 542 611 543 612 return NT_STATUS_OK; 544 } 545 546 /* Lookup groups a user is a member of. I wish Unix had a call like this! */ 547 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 548 TALLOC_CTX *mem_ctx, 549 const DOM_SID *user_sid, 550 uint32 *num_groups, DOM_SID **user_grpsids) 551 { 552 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 553 struct policy_handle dom_pol, user_pol; 554 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED; 555 struct samr_RidWithAttributeArray *rid_array = NULL; 556 unsigned int i; 557 uint32 user_rid; 558 struct rpc_pipe_client *cli; 559 560 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid))); 561 562 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 563 return NT_STATUS_UNSUCCESSFUL; 564 565 *num_groups = 0; 566 *user_grpsids = NULL; 567 568 /* so lets see if we have a cached user_info_3 */ 569 result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 570 num_groups, user_grpsids); 571 572 if (NT_STATUS_IS_OK(result)) { 573 return NT_STATUS_OK; 574 } 575 576 if ( !winbindd_can_contact_domain( domain ) ) { 577 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n", 578 domain->name)); 579 580 /* Tell the cache manager not to remember this one */ 581 582 return NT_STATUS_SYNCHRONIZATION_REQUIRED; 583 } 584 585 /* no cache; hit the wire */ 586 587 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 588 if (!NT_STATUS_IS_OK(result)) 589 return result; 590 591 /* Get user handle */ 592 result = rpccli_samr_OpenUser(cli, mem_ctx, 593 &dom_pol, 594 des_access, 595 user_rid, 596 &user_pol); 597 598 if (!NT_STATUS_IS_OK(result)) 599 return result; 600 601 /* Query user rids */ 602 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx, 603 &user_pol, 604 &rid_array); 605 *num_groups = rid_array->count; 606 607 rpccli_samr_Close(cli, mem_ctx, &user_pol); 608 609 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) 610 return result; 611 612 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups); 613 if (!(*user_grpsids)) 614 return NT_STATUS_NO_MEMORY; 615 616 for (i=0;i<(*num_groups);i++) { 617 sid_copy(&((*user_grpsids)[i]), &domain->sid); 618 sid_append_rid(&((*user_grpsids)[i]), 619 rid_array->rids[i].rid); 620 } 621 622 return NT_STATUS_OK; 623 } 624 613 } 614 615 NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx, 616 struct rpc_pipe_client *samr_pipe, 617 struct policy_handle *samr_policy, 618 uint32_t num_sids, 619 const struct dom_sid *sids, 620 uint32_t *pnum_aliases, 621 uint32_t **palias_rids) 622 { 625 623 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */ 626 627 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, 628 TALLOC_CTX *mem_ctx, 629 uint32 num_sids, const DOM_SID *sids, 630 uint32 *num_aliases, 631 uint32 **alias_rids) 632 { 633 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 634 struct policy_handle dom_pol; 635 uint32 num_query_sids = 0; 636 int i; 637 struct rpc_pipe_client *cli; 624 uint32_t num_query_sids = 0; 625 uint32_t num_queries = 1; 626 uint32_t num_aliases = 0; 627 uint32_t total_sids = 0; 628 uint32_t *alias_rids = NULL; 629 uint32_t rangesize = MAX_SAM_ENTRIES_W2K; 630 uint32_t i; 638 631 struct samr_Ids alias_rids_query; 639 int rangesize = MAX_SAM_ENTRIES_W2K; 640 uint32 total_sids = 0; 641 int num_queries = 1; 642 643 *num_aliases = 0; 644 *alias_rids = NULL; 645 646 DEBUG(3,("rpc: lookup_useraliases\n")); 647 648 if ( !winbindd_can_contact_domain( domain ) ) { 649 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n", 650 domain->name)); 651 return NT_STATUS_OK; 652 } 653 654 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 655 if (!NT_STATUS_IS_OK(result)) 656 return result; 632 NTSTATUS status, result; 633 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 657 634 658 635 do { … … 664 641 num_query_sids = MIN(num_sids - total_sids, rangesize); 665 642 666 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 667 num_queries, num_query_sids)); 643 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 644 num_queries, num_query_sids)); 668 645 669 646 if (num_query_sids) { … … 676 653 } 677 654 678 for (i=0; i<num_query_sids; i++) { 679 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]); 680 if (!sid_array.sids[i].sid) { 681 TALLOC_FREE(sid_array.sids); 655 for (i = 0; i < num_query_sids; i++) { 656 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]); 657 if (sid_array.sids[i].sid == NULL) { 682 658 return NT_STATUS_NO_MEMORY; 683 659 } … … 686 662 687 663 /* do request */ 688 result = rpccli_samr_GetAliasMembership(cli, mem_ctx, 689 &dom_pol, 664 status = dcerpc_samr_GetAliasMembership(b, 665 mem_ctx, 666 samr_policy, 690 667 &sid_array, 691 &alias_rids_query); 692 668 &alias_rids_query, 669 &result); 670 if (!NT_STATUS_IS_OK(status)) { 671 return status; 672 } 693 673 if (!NT_STATUS_IS_OK(result)) { 694 *num_aliases = 0; 695 *alias_rids = NULL; 696 TALLOC_FREE(sid_array.sids); 697 goto done; 674 return result; 698 675 } 699 676 700 677 /* process output */ 701 702 for (i=0; i<alias_rids_query.count; i++) {703 size_t na = *num_aliases; 704 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],705 alias_rids, &na)) {706 return NT_STATUS_NO_MEMORY;707 }708 *num_aliases = na;709 }710 711 TALLOC_FREE(sid_array.sids);678 for (i = 0; i < alias_rids_query.count; i++) { 679 size_t na = num_aliases; 680 681 if (!add_rid_to_array_unique(mem_ctx, 682 alias_rids_query.ids[i], 683 &alias_rids, 684 &na)) { 685 return NT_STATUS_NO_MEMORY; 686 } 687 num_aliases = na; 688 } 712 689 713 690 num_queries++; … … 715 692 } while (total_sids < num_sids); 716 693 717 done: 718 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries " 719 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize)); 720 721 return result; 722 } 723 694 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries " 695 "(rangesize: %d)\n", num_aliases, num_queries, rangesize)); 696 697 *pnum_aliases = num_aliases; 698 *palias_rids = alias_rids; 699 700 return NT_STATUS_OK; 701 #undef MAX_SAM_ENTRIES_W2K 702 } 724 703 725 704 /* Lookup group membership given a rid. */ 726 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 727 TALLOC_CTX *mem_ctx, 728 const DOM_SID *group_sid, 729 enum lsa_SidType type, 730 uint32 *num_names, 731 DOM_SID **sid_mem, char ***names, 732 uint32 **name_types) 733 { 734 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 735 uint32 i, total_names = 0; 736 struct policy_handle dom_pol, group_pol; 737 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED; 738 uint32 *rid_mem = NULL; 739 uint32 group_rid; 740 unsigned int j, r; 741 struct rpc_pipe_client *cli; 742 unsigned int orig_timeout; 743 struct samr_RidTypeArray *rids = NULL; 744 745 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, 746 sid_string_dbg(group_sid))); 747 748 if ( !winbindd_can_contact_domain( domain ) ) { 749 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n", 750 domain->name)); 751 return NT_STATUS_OK; 752 } 753 754 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) 705 NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx, 706 struct rpc_pipe_client *samr_pipe, 707 struct policy_handle *samr_policy, 708 const char *domain_name, 709 const struct dom_sid *domain_sid, 710 const struct dom_sid *group_sid, 711 enum lsa_SidType type, 712 uint32_t *pnum_names, 713 struct dom_sid **psid_mem, 714 char ***pnames, 715 uint32_t **pname_types) 716 { 717 struct policy_handle group_policy; 718 uint32_t group_rid; 719 uint32_t *rid_mem = NULL; 720 721 uint32_t num_names = 0; 722 uint32_t total_names = 0; 723 struct dom_sid *sid_mem = NULL; 724 char **names = NULL; 725 uint32_t *name_types = NULL; 726 727 struct lsa_Strings tmp_names; 728 struct samr_Ids tmp_types; 729 730 uint32_t j, r; 731 NTSTATUS status, result; 732 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 733 734 if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) { 755 735 return NT_STATUS_UNSUCCESSFUL; 756 757 *num_names = 0; 758 759 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 760 if (!NT_STATUS_IS_OK(result)) 761 return result; 762 763 result = rpccli_samr_OpenGroup(cli, mem_ctx, 764 &dom_pol, 765 des_access, 766 group_rid, 767 &group_pol); 768 769 if (!NT_STATUS_IS_OK(result)) 770 return result; 771 772 /* Step #1: Get a list of user rids that are the members of the 773 group. */ 774 775 /* This call can take a long time - allow the server to time out. 776 35 seconds should do it. */ 777 778 orig_timeout = rpccli_set_timeout(cli, 35000); 779 780 result = rpccli_samr_QueryGroupMember(cli, mem_ctx, 781 &group_pol, 782 &rids); 783 784 /* And restore our original timeout. */ 785 rpccli_set_timeout(cli, orig_timeout); 786 787 rpccli_samr_Close(cli, mem_ctx, &group_pol); 788 789 if (!NT_STATUS_IS_OK(result)) 790 return result; 791 792 if (!rids || !rids->count) { 793 names = NULL; 794 name_types = NULL; 795 sid_mem = NULL; 796 return NT_STATUS_OK; 797 } 798 799 *num_names = rids->count; 800 rid_mem = rids->rids; 801 802 /* Step #2: Convert list of rids into list of usernames. Do this 803 in bunches of ~1000 to avoid crashing NT4. It looks like there 804 is a buffer overflow or something like that lurking around 805 somewhere. */ 806 807 #define MAX_LOOKUP_RIDS 900 808 809 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names); 810 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names); 811 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names); 812 813 for (j=0;j<(*num_names);j++) 814 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]); 815 816 if (*num_names>0 && (!*names || !*name_types)) 817 return NT_STATUS_NO_MEMORY; 818 819 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) { 820 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS); 821 struct lsa_Strings tmp_names; 822 struct samr_Ids tmp_types; 823 824 /* Lookup a chunk of rids */ 825 826 result = rpccli_samr_LookupRids(cli, mem_ctx, 827 &dom_pol, 828 num_lookup_rids, 829 &rid_mem[i], 830 &tmp_names, 831 &tmp_types); 832 833 /* see if we have a real error (and yes the 834 STATUS_SOME_UNMAPPED is the one returned from 2k) */ 835 836 if (!NT_STATUS_IS_OK(result) && 837 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) 736 } 737 738 switch(type) { 739 case SID_NAME_DOM_GRP: 740 { 741 struct samr_RidAttrArray *rids = NULL; 742 743 status = dcerpc_samr_OpenGroup(b, 744 mem_ctx, 745 samr_policy, 746 SEC_FLAG_MAXIMUM_ALLOWED, 747 group_rid, 748 &group_policy, 749 &result); 750 if (!NT_STATUS_IS_OK(status)) { 751 return status; 752 } 753 if (!NT_STATUS_IS_OK(result)) { 838 754 return result; 839 840 /* Copy result into array. The talloc system will take 841 care of freeing the temporary arrays later on. */ 842 843 if (tmp_names.count != tmp_types.count) { 844 return NT_STATUS_UNSUCCESSFUL; 845 } 846 847 for (r=0; r<tmp_names.count; r++) { 848 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { 849 continue; 850 } 851 (*names)[total_names] = fill_domain_username_talloc( 852 mem_ctx, domain->name, 853 tmp_names.names[r].string, true); 854 (*name_types)[total_names] = tmp_types.ids[r]; 855 total_names += 1; 856 } 857 } 858 859 *num_names = total_names; 755 } 756 757 /* 758 * Step #1: Get a list of user rids that are the members of the group. 759 */ 760 status = dcerpc_samr_QueryGroupMember(b, 761 mem_ctx, 762 &group_policy, 763 &rids, 764 &result); 765 { 766 NTSTATUS _result; 767 dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result); 768 } 769 770 if (!NT_STATUS_IS_OK(status)) { 771 return status; 772 } 773 if (!NT_STATUS_IS_OK(result)) { 774 return result; 775 } 776 777 778 if (rids == NULL || rids->count == 0) { 779 pnum_names = 0; 780 pnames = NULL; 781 pname_types = NULL; 782 psid_mem = NULL; 783 784 return NT_STATUS_OK; 785 } 786 787 num_names = rids->count; 788 rid_mem = rids->rids; 789 790 break; 791 } 792 case SID_NAME_WKN_GRP: 793 case SID_NAME_ALIAS: 794 { 795 struct lsa_SidArray sid_array; 796 struct lsa_SidPtr sid_ptr; 797 struct samr_Ids rids_query; 798 799 sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid); 800 if (sid_ptr.sid == NULL) { 801 return NT_STATUS_NO_MEMORY; 802 } 803 804 sid_array.num_sids = 1; 805 sid_array.sids = &sid_ptr; 806 807 status = dcerpc_samr_GetAliasMembership(b, 808 mem_ctx, 809 samr_policy, 810 &sid_array, 811 &rids_query, 812 &result); 813 if (!NT_STATUS_IS_OK(status)) { 814 return status; 815 } 816 if (!NT_STATUS_IS_OK(result)) { 817 return result; 818 } 819 820 if (rids_query.count == 0) { 821 pnum_names = 0; 822 pnames = NULL; 823 pname_types = NULL; 824 psid_mem = NULL; 825 826 return NT_STATUS_OK; 827 } 828 829 num_names = rids_query.count; 830 rid_mem = rids_query.ids; 831 832 break; 833 } 834 default: 835 return NT_STATUS_UNSUCCESSFUL; 836 } 837 838 /* 839 * Step #2: Convert list of rids into list of usernames. 840 */ 841 if (num_names > 0) { 842 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names); 843 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names); 844 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names); 845 if (names == NULL || name_types == NULL || sid_mem == NULL) { 846 return NT_STATUS_NO_MEMORY; 847 } 848 } 849 850 for (j = 0; j < num_names; j++) { 851 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]); 852 } 853 854 status = dcerpc_samr_LookupRids(b, 855 mem_ctx, 856 samr_policy, 857 num_names, 858 rid_mem, 859 &tmp_names, 860 &tmp_types, 861 &result); 862 if (!NT_STATUS_IS_OK(status)) { 863 return status; 864 } 865 866 if (!NT_STATUS_IS_OK(result)) { 867 if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 868 return result; 869 } 870 } 871 872 /* Copy result into array. The talloc system will take 873 care of freeing the temporary arrays later on. */ 874 if (tmp_names.count != tmp_types.count) { 875 return NT_STATUS_UNSUCCESSFUL; 876 } 877 878 for (r = 0; r < tmp_names.count; r++) { 879 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { 880 continue; 881 } 882 names[total_names] = fill_domain_username_talloc(names, 883 domain_name, 884 tmp_names.names[r].string, 885 true); 886 if (names[total_names] == NULL) { 887 return NT_STATUS_NO_MEMORY; 888 } 889 name_types[total_names] = tmp_types.ids[r]; 890 total_names++; 891 } 892 893 *pnum_names = total_names; 894 *pnames = names; 895 *pname_types = name_types; 896 *psid_mem = sid_mem; 860 897 861 898 return NT_STATUS_OK; 862 899 } 863 900 864 #ifdef HAVE_LDAP 865 866 #include <ldap.h> 867 868 static int get_ldap_seq(const char *server, int port, uint32 *seq) 869 { 870 int ret = -1; 871 struct timeval to; 872 const char *attrs[] = {"highestCommittedUSN", NULL}; 873 LDAPMessage *res = NULL; 874 char **values = NULL; 875 LDAP *ldp = NULL; 876 877 *seq = DOM_SEQUENCE_NONE; 878 879 /* 880 * Parameterised (5) second timeout on open. This is needed as the 881 * search timeout doesn't seem to apply to doing an open as well. JRA. 882 */ 883 884 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout()); 885 if (ldp == NULL) 886 return -1; 887 888 /* Timeout if no response within 20 seconds. */ 889 to.tv_sec = 10; 890 to.tv_usec = 0; 891 892 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", 893 CONST_DISCARD(char **, attrs), 0, &to, &res)) 894 goto done; 895 896 if (ldap_count_entries(ldp, res) != 1) 897 goto done; 898 899 values = ldap_get_values(ldp, res, "highestCommittedUSN"); 900 if (!values || !values[0]) 901 goto done; 902 903 *seq = atoi(values[0]); 904 ret = 0; 905 906 done: 907 908 if (values) 909 ldap_value_free(values); 910 if (res) 911 ldap_msgfree(res); 912 if (ldp) 913 ldap_unbind(ldp); 914 return ret; 915 } 916 917 /********************************************************************** 918 Get the sequence number for a Windows AD native mode domain using 919 LDAP queries. 920 **********************************************************************/ 921 922 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq) 923 { 924 int ret = -1; 925 char addr[INET6_ADDRSTRLEN]; 926 927 print_sockaddr(addr, sizeof(addr), &domain->dcaddr); 928 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) { 929 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence " 930 "number for Domain (%s) from DC (%s)\n", 931 domain->name, addr)); 932 } 933 return ret; 934 } 935 936 #endif /* HAVE_LDAP */ 937 938 /* find the sequence number for a domain */ 939 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) 940 { 941 TALLOC_CTX *mem_ctx; 901 /* Find the sequence number for a domain */ 902 NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx, 903 struct rpc_pipe_client *samr_pipe, 904 struct policy_handle *samr_policy, 905 const char *domain_name, 906 uint32_t *pseq) 907 { 942 908 union samr_DomainInfo *info = NULL; 943 NTSTATUS result; 944 struct policy_handle dom_pol; 945 bool got_seq_num = False; 946 struct rpc_pipe_client *cli; 947 948 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); 949 950 if ( !winbindd_can_contact_domain( domain ) ) { 951 DEBUG(10,("sequence_number: No incoming trust for domain %s\n", 952 domain->name)); 953 *seq = time(NULL); 954 return NT_STATUS_OK; 955 } 956 957 *seq = DOM_SEQUENCE_NONE; 958 959 if (!(mem_ctx = talloc_init("sequence_number[rpc]"))) 960 return NT_STATUS_NO_MEMORY; 961 962 #ifdef HAVE_LDAP 963 if ( domain->active_directory ) 964 { 965 int res; 966 967 DEBUG(8,("using get_ldap_seq() to retrieve the " 968 "sequence number\n")); 969 970 res = get_ldap_sequence_number( domain, seq ); 971 if (res == 0) 972 { 973 result = NT_STATUS_OK; 974 DEBUG(10,("domain_sequence_number: LDAP for " 975 "domain %s is %u\n", 976 domain->name, *seq)); 977 goto done; 978 } 979 980 DEBUG(10,("domain_sequence_number: failed to get LDAP " 981 "sequence number for domain %s\n", 982 domain->name )); 983 } 984 #endif /* HAVE_LDAP */ 985 986 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 987 if (!NT_STATUS_IS_OK(result)) { 988 goto done; 989 } 990 991 /* Query domain info */ 992 993 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 994 &dom_pol, 909 bool got_seq_num = false; 910 NTSTATUS status, result; 911 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 912 913 /* query domain info */ 914 status = dcerpc_samr_QueryDomainInfo(b, 915 mem_ctx, 916 samr_policy, 995 917 8, 996 &info );997 998 if (NT_STATUS_IS_OK( result)) {999 * seq = info->info8.sequence_num;1000 got_seq_num = True;918 &info, 919 &result); 920 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 921 *pseq = info->info8.sequence_num; 922 got_seq_num = true; 1001 923 goto seq_num; 1002 924 } … … 1004 926 /* retry with info-level 2 in case the dc does not support info-level 8 1005 927 * (like all older samba2 and samba3 dc's) - Guenther */ 1006 1007 result = rpccli_samr_QueryDomainInfo(cli,mem_ctx,1008 &dom_pol,928 status = dcerpc_samr_QueryDomainInfo(b, 929 mem_ctx, 930 samr_policy, 1009 931 2, 1010 &info); 1011 1012 if (NT_STATUS_IS_OK(result)) { 1013 *seq = info->general.sequence_num; 1014 got_seq_num = True; 1015 } 1016 1017 seq_num: 932 &info, 933 &result); 934 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 935 *pseq = info->general.sequence_num; 936 got_seq_num = true; 937 goto seq_num; 938 } 939 940 if (!NT_STATUS_IS_OK(status)) { 941 goto seq_num; 942 } 943 944 status = result; 945 946 seq_num: 1018 947 if (got_seq_num) { 1019 948 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", 1020 domain ->name, (unsigned)*seq));949 domain_name, (unsigned) *pseq)); 1021 950 } else { 1022 951 DEBUG(10,("domain_sequence_number: failed to get sequence " 1023 952 "number (%u) for domain %s\n", 1024 (unsigned)*seq, domain->name )); 1025 } 1026 1027 done: 1028 1029 talloc_destroy(mem_ctx); 1030 1031 return result; 1032 } 1033 1034 /* get a list of trusted domains */ 1035 static NTSTATUS trusted_domains(struct winbindd_domain *domain, 1036 TALLOC_CTX *mem_ctx, 1037 struct netr_DomainTrustList *trusts) 1038 { 1039 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1040 uint32 enum_ctx = 0; 1041 struct rpc_pipe_client *cli; 1042 struct policy_handle lsa_policy; 1043 1044 DEBUG(3,("rpc: trusted_domains\n")); 1045 1046 ZERO_STRUCTP(trusts); 1047 1048 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1049 if (!NT_STATUS_IS_OK(result)) 1050 return result; 1051 1052 result = STATUS_MORE_ENTRIES; 1053 1054 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 1055 uint32 start_idx; 1056 int i; 953 (unsigned) *pseq, domain_name )); 954 status = NT_STATUS_OK; 955 } 956 957 return status; 958 } 959 960 /* Get a list of trusted domains */ 961 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx, 962 struct rpc_pipe_client *lsa_pipe, 963 struct policy_handle *lsa_policy, 964 uint32_t *pnum_trusts, 965 struct netr_DomainTrust **ptrusts) 966 { 967 struct netr_DomainTrust *array = NULL; 968 uint32_t enum_ctx = 0; 969 uint32_t count = 0; 970 NTSTATUS status, result; 971 struct dcerpc_binding_handle *b = lsa_pipe->binding_handle; 972 973 do { 1057 974 struct lsa_DomainList dom_list; 1058 1059 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx, 1060 &lsa_policy, 975 uint32_t start_idx; 976 uint32_t i; 977 978 /* 979 * We don't run into deadlocks here, cause winbind_off() is 980 * called in the main function. 981 */ 982 status = dcerpc_lsa_EnumTrustDom(b, 983 mem_ctx, 984 lsa_policy, 1061 985 &enum_ctx, 1062 986 &dom_list, 1063 (uint32_t)-1); 1064 1065 if (!NT_STATUS_IS_OK(result) && 1066 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 1067 break; 1068 1069 start_idx = trusts->count; 1070 trusts->count += dom_list.count; 1071 1072 trusts->array = talloc_realloc( 1073 mem_ctx, trusts->array, struct netr_DomainTrust, 1074 trusts->count); 1075 if (trusts->array == NULL) { 987 (uint32_t) -1, 988 &result); 989 if (!NT_STATUS_IS_OK(status)) { 990 return status; 991 } 992 if (!NT_STATUS_IS_OK(result)) { 993 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 994 return result; 995 } 996 } 997 998 start_idx = count; 999 count += dom_list.count; 1000 1001 array = talloc_realloc(mem_ctx, 1002 array, 1003 struct netr_DomainTrust, 1004 count); 1005 if (array == NULL) { 1076 1006 return NT_STATUS_NO_MEMORY; 1077 1007 } 1078 1008 1079 for (i =0; i<dom_list.count; i++) {1080 struct netr_DomainTrust *trust = & trusts->array[i];1009 for (i = 0; i < dom_list.count; i++) { 1010 struct netr_DomainTrust *trust = &array[i]; 1081 1011 struct dom_sid *sid; 1082 1012 1083 1013 ZERO_STRUCTP(trust); 1084 1014 1085 trust->netbios_name = talloc_move( 1086 trusts->array, 1087 &dom_list.domains[i].name.string); 1015 trust->netbios_name = talloc_move(array, 1016 &dom_list.domains[i].name.string); 1088 1017 trust->dns_name = NULL; 1089 1018 1090 sid = talloc( trusts->array, struct dom_sid);1019 sid = talloc(array, struct dom_sid); 1091 1020 if (sid == NULL) { 1092 1021 return NT_STATUS_NO_MEMORY; … … 1095 1024 trust->sid = sid; 1096 1025 } 1097 } 1026 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 1027 1028 *pnum_trusts = count; 1029 *ptrusts = array; 1030 1031 return NT_STATUS_OK; 1032 } 1033 1034 static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx, 1035 struct winbindd_domain *domain, 1036 struct lsa_SidArray *sids, 1037 struct lsa_RefDomainList **pdomains, 1038 struct lsa_TransNameArray **pnames) 1039 { 1040 struct lsa_TransNameArray2 lsa_names2; 1041 struct lsa_TransNameArray *names; 1042 uint32_t i, count; 1043 struct rpc_pipe_client *cli; 1044 NTSTATUS status, result; 1045 1046 status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli); 1047 if (!NT_STATUS_IS_OK(status)) { 1048 domain->can_do_ncacn_ip_tcp = false; 1049 return status; 1050 } 1051 1052 ZERO_STRUCT(lsa_names2); 1053 status = dcerpc_lsa_LookupSids3(cli->binding_handle, 1054 mem_ctx, 1055 sids, 1056 pdomains, 1057 &lsa_names2, 1058 LSA_LOOKUP_NAMES_ALL, 1059 &count, 1060 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES, 1061 LSA_CLIENT_REVISION_2, 1062 &result); 1063 if (!NT_STATUS_IS_OK(status)) { 1064 return status; 1065 } 1066 if (NT_STATUS_IS_ERR(result)) { 1067 return result; 1068 } 1069 names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); 1070 if (names == NULL) { 1071 return NT_STATUS_NO_MEMORY; 1072 } 1073 names->count = lsa_names2.count; 1074 names->names = talloc_array(names, struct lsa_TranslatedName, 1075 names->count); 1076 if (names->names == NULL) { 1077 return NT_STATUS_NO_MEMORY; 1078 } 1079 for (i=0; i<names->count; i++) { 1080 names->names[i].sid_type = lsa_names2.names[i].sid_type; 1081 names->names[i].name.string = talloc_move( 1082 names->names, &lsa_names2.names[i].name.string); 1083 names->names[i].sid_index = lsa_names2.names[i].sid_index; 1084 } 1085 *pnames = names; 1098 1086 return result; 1099 1087 } 1100 1088 1101 /* find the lockout policy for a domain */ 1102 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, 1103 TALLOC_CTX *mem_ctx, 1104 struct samr_DomInfo12 *lockout_policy) 1105 { 1106 NTSTATUS result; 1107 struct rpc_pipe_client *cli; 1108 struct policy_handle dom_pol; 1109 union samr_DomainInfo *info = NULL; 1110 1111 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name)); 1112 1113 if ( !winbindd_can_contact_domain( domain ) ) { 1114 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n", 1115 domain->name)); 1116 return NT_STATUS_NOT_SUPPORTED; 1117 } 1118 1119 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 1120 if (!NT_STATUS_IS_OK(result)) { 1121 goto done; 1122 } 1123 1124 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 1125 &dom_pol, 1126 12, 1127 &info); 1128 if (!NT_STATUS_IS_OK(result)) { 1129 goto done; 1130 } 1131 1132 *lockout_policy = info->info12; 1133 1134 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n", 1135 info->info12.lockout_threshold)); 1136 1137 done: 1138 1139 return result; 1140 } 1141 1142 /* find the password policy for a domain */ 1143 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, 1144 TALLOC_CTX *mem_ctx, 1145 struct samr_DomInfo1 *password_policy) 1146 { 1147 NTSTATUS result; 1148 struct rpc_pipe_client *cli; 1149 struct policy_handle dom_pol; 1150 union samr_DomainInfo *info = NULL; 1151 1152 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name)); 1153 1154 if ( !winbindd_can_contact_domain( domain ) ) { 1155 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n", 1156 domain->name)); 1157 return NT_STATUS_NOT_SUPPORTED; 1158 } 1159 1160 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 1161 if (!NT_STATUS_IS_OK(result)) { 1162 goto done; 1163 } 1164 1165 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 1166 &dom_pol, 1167 1, 1168 &info); 1169 if (!NT_STATUS_IS_OK(result)) { 1170 goto done; 1171 } 1172 1173 *password_policy = info->info1; 1174 1175 DEBUG(10,("msrpc_password_policy: min_length_password %d\n", 1176 info->info1.min_password_length)); 1177 1178 done: 1179 1180 return result; 1181 } 1182 1183 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli, 1184 TALLOC_CTX *mem_ctx, 1185 struct policy_handle *pol, 1186 int num_sids, 1187 const DOM_SID *sids, 1188 char ***pdomains, 1189 char ***pnames, 1190 enum lsa_SidType **ptypes); 1191 1192 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, 1193 struct winbindd_domain *domain, 1194 uint32_t num_sids, 1195 const struct dom_sid *sids, 1196 char ***domains, 1197 char ***names, 1198 enum lsa_SidType **types) 1199 { 1200 NTSTATUS status; 1089 NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, 1090 struct winbindd_domain *domain, 1091 struct lsa_SidArray *sids, 1092 struct lsa_RefDomainList **pdomains, 1093 struct lsa_TransNameArray **pnames) 1094 { 1095 struct lsa_TransNameArray *names; 1201 1096 struct rpc_pipe_client *cli = NULL; 1202 1097 struct policy_handle lsa_policy; 1203 u nsigned int orig_timeout;1204 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;1098 uint32_t count; 1099 NTSTATUS status, result; 1205 1100 1206 1101 if (domain->can_do_ncacn_ip_tcp) { 1207 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);1208 if (NT_STATUS_IS_OK(status)) {1209 lookup_sids_fn = rpccli_lsa_lookup_sids3;1210 goto lookup;1211 } 1212 domain->can_do_ncacn_ip_tcp = false;1213 } 1102 status = rpc_try_lookup_sids3(mem_ctx, domain, sids, 1103 pdomains, pnames); 1104 if (!NT_STATUS_IS_ERR(status)) { 1105 return status; 1106 } 1107 } 1108 1214 1109 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1215 1216 1110 if (!NT_STATUS_IS_OK(status)) { 1217 1111 return status; 1218 1112 } 1219 1113 1220 lookup: 1221 /* 1222 * This call can take a long time 1223 * allow the server to time out. 1224 * 35 seconds should do it. 1225 */ 1226 orig_timeout = rpccli_set_timeout(cli, 35000); 1227 1228 status = lookup_sids_fn(cli, 1229 mem_ctx, 1230 &lsa_policy, 1231 num_sids, 1232 sids, 1233 domains, 1234 names, 1235 types); 1236 1237 /* And restore our original timeout. */ 1238 rpccli_set_timeout(cli, orig_timeout); 1239 1240 if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED || 1241 NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) { 1242 /* 1243 * This can happen if the schannel key is not 1244 * valid anymore, we need to invalidate the 1245 * all connections to the dc and reestablish 1246 * a netlogon connection first. 1247 */ 1248 invalidate_cm_connection(&domain->conn); 1249 status = NT_STATUS_ACCESS_DENIED; 1250 } 1251 1114 names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); 1115 if (names == NULL) { 1116 return NT_STATUS_NO_MEMORY; 1117 } 1118 status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx, 1119 &lsa_policy, sids, pdomains, 1120 names, LSA_LOOKUP_NAMES_ALL, 1121 &count, &result); 1252 1122 if (!NT_STATUS_IS_OK(status)) { 1253 1123 return status; 1254 1124 } 1255 1256 return status; 1257 } 1258 1259 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli, 1260 TALLOC_CTX *mem_ctx, 1261 struct policy_handle *pol, 1262 int num_names, 1263 const char **names, 1264 const char ***dom_names, 1265 int level, 1266 struct dom_sid **sids, 1267 enum lsa_SidType **types); 1268 1269 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, 1270 struct winbindd_domain *domain, 1271 uint32_t num_names, 1272 const char **names, 1273 const char ***domains, 1274 struct dom_sid **sids, 1275 enum lsa_SidType **types) 1276 { 1277 NTSTATUS status; 1278 struct rpc_pipe_client *cli = NULL; 1279 struct policy_handle lsa_policy; 1280 unsigned int orig_timeout = 0; 1281 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names; 1282 1283 if (domain->can_do_ncacn_ip_tcp) { 1284 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli); 1285 if (NT_STATUS_IS_OK(status)) { 1286 lookup_names_fn = rpccli_lsa_lookup_names4; 1287 goto lookup; 1288 } 1289 domain->can_do_ncacn_ip_tcp = false; 1290 } 1291 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1292 1293 if (!NT_STATUS_IS_OK(status)) { 1294 return status; 1295 } 1296 1297 lookup: 1298 1299 /* 1300 * This call can take a long time 1301 * allow the server to time out. 1302 * 35 seconds should do it. 1303 */ 1304 orig_timeout = rpccli_set_timeout(cli, 35000); 1305 1306 status = lookup_names_fn(cli, 1307 mem_ctx, 1308 &lsa_policy, 1309 num_names, 1310 (const char **) names, 1311 domains, 1312 1, 1313 sids, 1314 types); 1315 1316 /* And restore our original timeout. */ 1317 rpccli_set_timeout(cli, orig_timeout); 1318 1319 if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED || 1320 NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) { 1321 /* 1322 * This can happen if the schannel key is not 1323 * valid anymore, we need to invalidate the 1324 * all connections to the dc and reestablish 1325 * a netlogon connection first. 1326 */ 1327 invalidate_cm_connection(&domain->conn); 1328 status = NT_STATUS_ACCESS_DENIED; 1329 } 1330 1331 if (!NT_STATUS_IS_OK(status)) { 1332 return status; 1333 } 1334 1335 return status; 1336 } 1337 1338 /* the rpc backend methods are exposed via this structure */ 1339 struct winbindd_methods msrpc_methods = { 1340 False, 1341 query_user_list, 1342 enum_dom_groups, 1343 enum_local_groups, 1344 msrpc_name_to_sid, 1345 msrpc_sid_to_name, 1346 msrpc_rids_to_names, 1347 query_user, 1348 lookup_usergroups, 1349 msrpc_lookup_useraliases, 1350 lookup_groupmem, 1351 sequence_number, 1352 msrpc_lockout_policy, 1353 msrpc_password_policy, 1354 trusted_domains, 1355 }; 1125 if (NT_STATUS_IS_ERR(result)) { 1126 return result; 1127 } 1128 *pnames = names; 1129 return result; 1130 }
Note:
See TracChangeset
for help on using the changeset viewer.