Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Helpers to add users and groups to the DB
5 :
6 : Copyright (C) Andrew Tridgell 2004
7 : Copyright (C) Volker Lendecke 2004
8 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2010
9 : Copyright (C) Matthias Dieter Wallnöfer 2009
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 : */
24 :
25 : #include "includes.h"
26 : #include "dsdb/samdb/samdb.h"
27 : #include "dsdb/common/util.h"
28 : #include "../libds/common/flags.h"
29 : #include "libcli/security/security.h"
30 :
31 : #include "libds/common/flag_mapping.h"
32 :
33 : /* Add a user, SAMR style, including the correct transaction
34 : * semantics. Used by the SAMR server and by pdb_samba4 */
35 884 : NTSTATUS dsdb_add_user(struct ldb_context *ldb,
36 : TALLOC_CTX *mem_ctx,
37 : const char *account_name,
38 : uint32_t acct_flags,
39 : const struct dom_sid *forced_sid,
40 : struct dom_sid **sid,
41 : struct ldb_dn **dn)
42 : {
43 : const char *name;
44 : struct ldb_message *msg;
45 : int ret;
46 884 : const char *container, *obj_class=NULL;
47 : char *cn_name;
48 : size_t cn_name_len;
49 :
50 884 : const char *attrs[] = {
51 : "objectSid",
52 : "userAccountControl",
53 : NULL
54 : };
55 :
56 : uint32_t user_account_control;
57 : struct ldb_dn *account_dn;
58 : struct dom_sid *account_sid;
59 :
60 884 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
61 884 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
62 :
63 : /*
64 : * Start a transaction, so we can query and do a subsequent atomic
65 : * modify
66 : */
67 :
68 884 : ret = ldb_transaction_start(ldb);
69 884 : if (ret != LDB_SUCCESS) {
70 0 : DEBUG(0,("Failed to start a transaction for user creation: %s\n",
71 : ldb_errstring(ldb)));
72 0 : talloc_free(tmp_ctx);
73 0 : return NT_STATUS_LOCK_NOT_GRANTED;
74 : }
75 :
76 : /* check if the user already exists */
77 884 : name = samdb_search_string(ldb, tmp_ctx, NULL,
78 : "sAMAccountName",
79 : "(&(sAMAccountName=%s)(objectclass=user))",
80 : ldb_binary_encode_string(tmp_ctx, account_name));
81 884 : if (name != NULL) {
82 2 : ldb_transaction_cancel(ldb);
83 2 : talloc_free(tmp_ctx);
84 2 : return NT_STATUS_USER_EXISTS;
85 : }
86 :
87 882 : cn_name = talloc_strdup(tmp_ctx, account_name);
88 882 : if (!cn_name) {
89 0 : ldb_transaction_cancel(ldb);
90 0 : talloc_free(tmp_ctx);
91 0 : return NT_STATUS_NO_MEMORY;
92 : }
93 :
94 882 : cn_name_len = strlen(cn_name);
95 882 : if (cn_name_len < 1) {
96 0 : ldb_transaction_cancel(ldb);
97 0 : talloc_free(tmp_ctx);
98 0 : return NT_STATUS_INVALID_PARAMETER;
99 : }
100 :
101 882 : msg = ldb_msg_new(tmp_ctx);
102 882 : if (msg == NULL) {
103 0 : ldb_transaction_cancel(ldb);
104 0 : talloc_free(tmp_ctx);
105 0 : return NT_STATUS_NO_MEMORY;
106 : }
107 :
108 : /* This must be one of these values *only* */
109 882 : if (acct_flags == ACB_NORMAL) {
110 499 : container = "CN=Users";
111 499 : obj_class = "user";
112 499 : user_account_control = UF_NORMAL_ACCOUNT;
113 383 : } else if (acct_flags == ACB_WSTRUST) {
114 148 : if (cn_name[cn_name_len - 1] != '$') {
115 0 : ldb_transaction_cancel(ldb);
116 0 : return NT_STATUS_FOOBAR;
117 : }
118 148 : cn_name[cn_name_len - 1] = '\0';
119 148 : container = "CN=Computers";
120 148 : obj_class = "computer";
121 148 : user_account_control = UF_WORKSTATION_TRUST_ACCOUNT;
122 :
123 235 : } else if (acct_flags == ACB_SVRTRUST) {
124 135 : if (cn_name[cn_name_len - 1] != '$') {
125 0 : ldb_transaction_cancel(ldb);
126 0 : return NT_STATUS_FOOBAR;
127 : }
128 135 : cn_name[cn_name_len - 1] = '\0';
129 135 : container = "OU=Domain Controllers";
130 135 : obj_class = "computer";
131 135 : user_account_control = UF_SERVER_TRUST_ACCOUNT;
132 100 : } else if (acct_flags == ACB_DOMTRUST) {
133 0 : DEBUG(3, ("Invalid account flags specified: cannot create domain trusts via this interface (must use LSA CreateTrustedDomain calls\n"));
134 0 : ldb_transaction_cancel(ldb);
135 0 : talloc_free(tmp_ctx);
136 0 : return NT_STATUS_INVALID_PARAMETER;
137 : } else {
138 100 : DEBUG(3, ("Invalid account flags specified 0x%08X, must be exactly one of \n"
139 : "ACB_NORMAL (0x%08X) ACB_WSTRUST (0x%08X) or ACB_SVRTRUST (0x%08X)\n",
140 : acct_flags,
141 : ACB_NORMAL, ACB_WSTRUST, ACB_SVRTRUST));
142 100 : ldb_transaction_cancel(ldb);
143 100 : talloc_free(tmp_ctx);
144 100 : return NT_STATUS_INVALID_PARAMETER;
145 : }
146 :
147 782 : user_account_control |= UF_ACCOUNTDISABLE | UF_PASSWD_NOTREQD;
148 :
149 : /* add core elements to the ldb_message for the user */
150 782 : msg->dn = ldb_dn_copy(msg, ldb_get_default_basedn(ldb));
151 782 : if ( ! ldb_dn_add_child_fmt(msg->dn, "CN=%s,%s", cn_name, container)) {
152 0 : ldb_transaction_cancel(ldb);
153 0 : talloc_free(tmp_ctx);
154 0 : return NT_STATUS_FOOBAR;
155 : }
156 :
157 782 : ret = ldb_msg_add_string(msg, "sAMAccountName", account_name);
158 782 : if (ret != LDB_SUCCESS) {
159 0 : goto failed;
160 : }
161 782 : ret = ldb_msg_add_string(msg, "objectClass", obj_class);
162 782 : if (ret != LDB_SUCCESS) {
163 0 : goto failed;
164 : }
165 782 : ret = samdb_msg_add_uint(ldb, tmp_ctx, msg,
166 : "userAccountControl",
167 : user_account_control);
168 782 : if (ret != LDB_SUCCESS) {
169 0 : goto failed;
170 : }
171 :
172 : /* This is only here for migrations using pdb_samba4, the
173 : * caller and the samldb are responsible for ensuring it makes
174 : * sense */
175 782 : if (forced_sid) {
176 1 : ret = samdb_msg_add_dom_sid(ldb, msg, msg, "objectSID", forced_sid);
177 1 : if (ret != LDB_SUCCESS) {
178 0 : ldb_transaction_cancel(ldb);
179 0 : talloc_free(tmp_ctx);
180 0 : return NT_STATUS_INTERNAL_ERROR;
181 : }
182 : }
183 :
184 : /* create the user */
185 782 : ret = ldb_add(ldb, msg);
186 782 : switch (ret) {
187 779 : case LDB_SUCCESS:
188 779 : break;
189 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
190 0 : ldb_transaction_cancel(ldb);
191 0 : DEBUG(0,("Failed to create user record %s: %s\n",
192 : ldb_dn_get_linearized(msg->dn),
193 : ldb_errstring(ldb)));
194 0 : talloc_free(tmp_ctx);
195 0 : return NT_STATUS_USER_EXISTS;
196 3 : case LDB_ERR_UNWILLING_TO_PERFORM:
197 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
198 3 : ldb_transaction_cancel(ldb);
199 3 : DEBUG(0,("Failed to create user record %s: %s\n",
200 : ldb_dn_get_linearized(msg->dn),
201 : ldb_errstring(ldb)));
202 3 : talloc_free(tmp_ctx);
203 3 : return NT_STATUS_ACCESS_DENIED;
204 0 : default:
205 0 : ldb_transaction_cancel(ldb);
206 0 : DEBUG(0,("Failed to create user record %s: %s\n",
207 : ldb_dn_get_linearized(msg->dn),
208 : ldb_errstring(ldb)));
209 0 : talloc_free(tmp_ctx);
210 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
211 : }
212 :
213 779 : account_dn = msg->dn;
214 :
215 : /* retrieve the sid and account control bits for the user just created */
216 779 : ret = dsdb_search_one(ldb, tmp_ctx, &msg,
217 : account_dn, LDB_SCOPE_BASE, attrs, 0, NULL);
218 :
219 779 : if (ret != LDB_SUCCESS) {
220 0 : ldb_transaction_cancel(ldb);
221 0 : DEBUG(0,("Can't locate the account we just created %s: %s\n",
222 : ldb_dn_get_linearized(account_dn), ldb_errstring(ldb)));
223 0 : talloc_free(tmp_ctx);
224 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
225 : }
226 779 : account_sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
227 779 : if (account_sid == NULL) {
228 0 : ldb_transaction_cancel(ldb);
229 0 : DEBUG(0,("Apparently we failed to get the objectSid of the just created account record %s\n",
230 : ldb_dn_get_linearized(msg->dn)));
231 0 : talloc_free(tmp_ctx);
232 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
233 : }
234 :
235 779 : ret = ldb_transaction_commit(ldb);
236 779 : if (ret != LDB_SUCCESS) {
237 0 : DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
238 : ldb_dn_get_linearized(msg->dn),
239 : ldb_errstring(ldb)));
240 0 : talloc_free(tmp_ctx);
241 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
242 : }
243 779 : *dn = talloc_steal(mem_ctx, account_dn);
244 779 : if (sid) {
245 778 : *sid = talloc_steal(mem_ctx, account_sid);
246 : }
247 779 : talloc_free(tmp_ctx);
248 779 : return NT_STATUS_OK;
249 :
250 0 : failed:
251 0 : ldb_transaction_cancel(ldb);
252 0 : talloc_free(tmp_ctx);
253 0 : return NT_STATUS_INTERNAL_ERROR;
254 : }
255 :
256 : /*
257 : called by samr_CreateDomainGroup and pdb_samba4
258 : */
259 529 : NTSTATUS dsdb_add_domain_group(struct ldb_context *ldb,
260 : TALLOC_CTX *mem_ctx,
261 : const char *groupname,
262 : struct dom_sid **sid,
263 : struct ldb_dn **dn)
264 : {
265 : const char *name;
266 : struct ldb_message *msg;
267 : struct dom_sid *group_sid;
268 : int ret;
269 :
270 529 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
271 529 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
272 :
273 : /* check if the group already exists */
274 529 : name = samdb_search_string(ldb, tmp_ctx, NULL,
275 : "sAMAccountName",
276 : "(&(sAMAccountName=%s)(objectclass=group))",
277 : ldb_binary_encode_string(tmp_ctx, groupname));
278 529 : if (name != NULL) {
279 1 : return NT_STATUS_GROUP_EXISTS;
280 : }
281 :
282 528 : msg = ldb_msg_new(tmp_ctx);
283 528 : if (msg == NULL) {
284 0 : return NT_STATUS_NO_MEMORY;
285 : }
286 :
287 : /* add core elements to the ldb_message for the user */
288 528 : msg->dn = ldb_dn_copy(tmp_ctx, ldb_get_default_basedn(ldb));
289 528 : ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", groupname);
290 528 : if (!msg->dn) {
291 0 : talloc_free(tmp_ctx);
292 0 : return NT_STATUS_NO_MEMORY;
293 : }
294 528 : ldb_msg_add_string(msg, "sAMAccountName", groupname);
295 528 : ldb_msg_add_string(msg, "objectClass", "group");
296 :
297 : /* create the group */
298 528 : ret = ldb_add(ldb, msg);
299 528 : switch (ret) {
300 528 : case LDB_SUCCESS:
301 528 : break;
302 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
303 0 : DEBUG(0,("Failed to create group record %s: %s\n",
304 : ldb_dn_get_linearized(msg->dn),
305 : ldb_errstring(ldb)));
306 0 : talloc_free(tmp_ctx);
307 0 : return NT_STATUS_GROUP_EXISTS;
308 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
309 0 : DEBUG(0,("Failed to create group record %s: %s\n",
310 : ldb_dn_get_linearized(msg->dn),
311 : ldb_errstring(ldb)));
312 0 : talloc_free(tmp_ctx);
313 0 : return NT_STATUS_ACCESS_DENIED;
314 0 : default:
315 0 : DEBUG(0,("Failed to create group record %s: %s\n",
316 : ldb_dn_get_linearized(msg->dn),
317 : ldb_errstring(ldb)));
318 0 : talloc_free(tmp_ctx);
319 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
320 : }
321 :
322 : /* retrieve the sid for the group just created */
323 528 : group_sid = samdb_search_dom_sid(ldb, tmp_ctx,
324 : msg->dn, "objectSid", NULL);
325 528 : if (group_sid == NULL) {
326 0 : return NT_STATUS_UNSUCCESSFUL;
327 : }
328 :
329 528 : *dn = talloc_steal(mem_ctx, msg->dn);
330 528 : *sid = talloc_steal(mem_ctx, group_sid);
331 528 : talloc_free(tmp_ctx);
332 528 : return NT_STATUS_OK;
333 : }
334 :
335 453 : NTSTATUS dsdb_add_domain_alias(struct ldb_context *ldb,
336 : TALLOC_CTX *mem_ctx,
337 : const char *alias_name,
338 : struct dom_sid **sid,
339 : struct ldb_dn **dn)
340 : {
341 : const char *name;
342 : struct ldb_message *msg;
343 : struct dom_sid *alias_sid;
344 : int ret;
345 :
346 453 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
347 453 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
348 :
349 453 : if (ldb_transaction_start(ldb) != LDB_SUCCESS) {
350 0 : DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(ldb)));
351 0 : return NT_STATUS_INTERNAL_ERROR;
352 : }
353 :
354 : /* Check if alias already exists */
355 453 : name = samdb_search_string(ldb, tmp_ctx, NULL,
356 : "sAMAccountName",
357 : "(sAMAccountName=%s)(objectclass=group))",
358 : ldb_binary_encode_string(mem_ctx, alias_name));
359 :
360 453 : if (name != NULL) {
361 0 : talloc_free(tmp_ctx);
362 0 : ldb_transaction_cancel(ldb);
363 0 : return NT_STATUS_ALIAS_EXISTS;
364 : }
365 :
366 453 : msg = ldb_msg_new(tmp_ctx);
367 453 : if (msg == NULL) {
368 0 : talloc_free(tmp_ctx);
369 0 : ldb_transaction_cancel(ldb);
370 0 : return NT_STATUS_NO_MEMORY;
371 : }
372 :
373 : /* add core elements to the ldb_message for the alias */
374 453 : msg->dn = ldb_dn_copy(mem_ctx, ldb_get_default_basedn(ldb));
375 453 : ldb_dn_add_child_fmt(msg->dn, "CN=%s,CN=Users", alias_name);
376 453 : if (!msg->dn) {
377 0 : talloc_free(tmp_ctx);
378 0 : ldb_transaction_cancel(ldb);
379 0 : return NT_STATUS_NO_MEMORY;
380 : }
381 :
382 453 : ldb_msg_add_string(msg, "sAMAccountName", alias_name);
383 453 : ldb_msg_add_string(msg, "objectClass", "group");
384 453 : samdb_msg_add_int(ldb, mem_ctx, msg, "groupType", GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
385 :
386 : /* create the alias */
387 453 : ret = ldb_add(ldb, msg);
388 453 : switch (ret) {
389 453 : case LDB_SUCCESS:
390 453 : break;
391 0 : case LDB_ERR_ENTRY_ALREADY_EXISTS:
392 0 : talloc_free(tmp_ctx);
393 0 : ldb_transaction_cancel(ldb);
394 0 : return NT_STATUS_ALIAS_EXISTS;
395 0 : case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
396 0 : talloc_free(tmp_ctx);
397 0 : ldb_transaction_cancel(ldb);
398 0 : return NT_STATUS_ACCESS_DENIED;
399 0 : default:
400 0 : DEBUG(0,("Failed to create alias record %s: %s\n",
401 : ldb_dn_get_linearized(msg->dn),
402 : ldb_errstring(ldb)));
403 0 : talloc_free(tmp_ctx);
404 0 : ldb_transaction_cancel(ldb);
405 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
406 : }
407 :
408 : /* retrieve the sid for the alias just created */
409 453 : alias_sid = samdb_search_dom_sid(ldb, tmp_ctx,
410 : msg->dn, "objectSid", NULL);
411 :
412 453 : if (ldb_transaction_commit(ldb) != LDB_SUCCESS) {
413 0 : DEBUG(0, ("Failed to commit transaction in dsdb_add_domain_alias(): %s\n",
414 : ldb_errstring(ldb)));
415 0 : return NT_STATUS_INTERNAL_ERROR;
416 : }
417 :
418 453 : *dn = talloc_steal(mem_ctx, msg->dn);
419 453 : *sid = talloc_steal(mem_ctx, alias_sid);
420 453 : talloc_free(tmp_ctx);
421 :
422 :
423 453 : return NT_STATUS_OK;
424 : }
425 :
426 : /* Return the members of this group (which may be a domain group or an alias) */
427 237 : NTSTATUS dsdb_enum_group_mem(struct ldb_context *ldb,
428 : TALLOC_CTX *mem_ctx,
429 : struct ldb_dn *dn,
430 : struct dom_sid **members_out,
431 : unsigned int *pnum_members)
432 : {
433 : struct ldb_message *msg;
434 : unsigned int i, j;
435 : int ret;
436 : struct dom_sid *members;
437 : struct ldb_message_element *member_el;
438 237 : const char *attrs[] = { "member", NULL };
439 : NTSTATUS status;
440 237 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
441 237 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
442 :
443 237 : ret = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs,
444 : DSDB_SEARCH_SHOW_EXTENDED_DN, NULL);
445 237 : if (ret == LDB_ERR_NO_SUCH_OBJECT) {
446 0 : talloc_free(tmp_ctx);
447 0 : return NT_STATUS_OBJECT_NAME_NOT_FOUND;
448 : }
449 237 : if (ret != LDB_SUCCESS) {
450 0 : DEBUG(1, ("dsdb_enum_group_mem: dsdb_search for %s failed: %s\n",
451 : ldb_dn_get_linearized(dn), ldb_errstring(ldb)));
452 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
453 : }
454 :
455 237 : member_el = ldb_msg_find_element(msg, "member");
456 237 : if (!member_el) {
457 110 : *members_out = NULL;
458 110 : *pnum_members = 0;
459 110 : talloc_free(tmp_ctx);
460 110 : return NT_STATUS_OK;
461 : }
462 :
463 127 : members = talloc_array(mem_ctx, struct dom_sid, member_el->num_values);
464 127 : if (members == NULL) {
465 0 : return NT_STATUS_NO_MEMORY;
466 : }
467 :
468 127 : j = 0;
469 290 : for (i=0; i <member_el->num_values; i++) {
470 163 : struct ldb_dn *member_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb,
471 163 : &member_el->values[i]);
472 163 : if (!member_dn || !ldb_dn_validate(member_dn)) {
473 0 : DEBUG(1, ("Could not parse %*.*s as a DN\n",
474 : (int)member_el->values[i].length,
475 : (int)member_el->values[i].length,
476 : (const char *)member_el->values[i].data));
477 0 : talloc_free(tmp_ctx);
478 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
479 : }
480 :
481 163 : status = dsdb_get_extended_dn_sid(member_dn, &members[j],
482 : "SID");
483 163 : if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
484 : /* If we fail finding a SID then this is no error since
485 : * it could be a non SAM object - e.g. a contact */
486 0 : continue;
487 163 : } else if (!NT_STATUS_IS_OK(status)) {
488 0 : DEBUG(1, ("When parsing DN '%s' we failed to parse it's SID component, so we cannot fetch the membership: %s\n",
489 : ldb_dn_get_extended_linearized(tmp_ctx, member_dn, 1),
490 : nt_errstr(status)));
491 0 : talloc_free(tmp_ctx);
492 0 : return status;
493 : }
494 :
495 163 : ++j;
496 : }
497 :
498 127 : *members_out = members;
499 127 : *pnum_members = j;
500 127 : talloc_free(tmp_ctx);
501 127 : return NT_STATUS_OK;
502 : }
503 :
504 2397 : NTSTATUS dsdb_lookup_rids(struct ldb_context *ldb,
505 : TALLOC_CTX *mem_ctx,
506 : const struct dom_sid *domain_sid,
507 : unsigned int num_rids,
508 : uint32_t *rids,
509 : const char **names,
510 : enum lsa_SidType *lsa_attrs)
511 : {
512 2397 : const char *attrs[] = { "sAMAccountType", "sAMAccountName", NULL };
513 : unsigned int i, num_mapped;
514 :
515 2397 : TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
516 2397 : NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
517 :
518 2397 : num_mapped = 0;
519 :
520 4866 : for (i=0; i<num_rids; i++) {
521 : struct ldb_message *msg;
522 : struct ldb_dn *dn;
523 : uint32_t attr;
524 : int rc;
525 :
526 2469 : lsa_attrs[i] = SID_NAME_UNKNOWN;
527 :
528 2469 : dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<SID=%s>",
529 : dom_sid_string(tmp_ctx,
530 2469 : dom_sid_add_rid(tmp_ctx, domain_sid,
531 2469 : rids[i])));
532 2469 : if (dn == NULL) {
533 0 : talloc_free(tmp_ctx);
534 0 : return NT_STATUS_NO_MEMORY;
535 : }
536 2469 : rc = dsdb_search_one(ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "samAccountName=*");
537 2469 : if (rc == LDB_ERR_NO_SUCH_OBJECT) {
538 2 : continue;
539 2468 : } else if (rc != LDB_SUCCESS) {
540 0 : talloc_free(tmp_ctx);
541 0 : return NT_STATUS_INTERNAL_DB_CORRUPTION;
542 : }
543 :
544 2468 : names[i] = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
545 2468 : if (names[i] == NULL) {
546 0 : DEBUG(10, ("no samAccountName\n"));
547 0 : continue;
548 : }
549 2468 : talloc_steal(names, names[i]);
550 2468 : attr = ldb_msg_find_attr_as_uint(msg, "samAccountType", 0);
551 2468 : lsa_attrs[i] = ds_atype_map(attr);
552 2468 : if (lsa_attrs[i] == SID_NAME_UNKNOWN) {
553 0 : continue;
554 : }
555 2468 : num_mapped += 1;
556 : }
557 2397 : talloc_free(tmp_ctx);
558 :
559 2397 : if (num_mapped == 0) {
560 0 : return NT_STATUS_NONE_MAPPED;
561 : }
562 2397 : if (num_mapped < num_rids) {
563 1 : return STATUS_SOME_UNMAPPED;
564 : }
565 2396 : return NT_STATUS_OK;
566 : }
567 :
|