2 Unix SMB/CIFS implementation.
4 interface functions for the sam database
6 Copyright (C) Andrew Tridgell 2004
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "librpc/gen_ndr/ndr_netlogon.h"
25 #include "librpc/gen_ndr/ndr_misc.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "system/time.h"
28 #include "system/filesys.h"
32 connect to the SAM database
33 return an opaque context pointer on success, or NULL on failure
35 struct ldb_context *samdb_connect(TALLOC_CTX *mem_ctx, struct auth_session_info *session_info)
37 struct ldb_context *ldb;
38 ldb = ldb_wrap_connect(mem_ctx, lp_sam_url(), 0, NULL);
39 if (ldb_set_opaque(ldb, "sessionInfo", session_info)) {
46 search the sam for the specified attributes in a specific domain, filter on
47 objectSid being in domain_sid.
49 int samdb_search_domain(struct ldb_context *sam_ldb,
51 const struct ldb_dn *basedn,
52 struct ldb_message ***res,
53 const char * const *attrs,
54 const struct dom_sid *domain_sid,
55 const char *format, ...) _PRINTF_ATTRIBUTE(7,8)
61 count = gendb_search_v(sam_ldb, mem_ctx, basedn,
62 res, attrs, format, ap);
68 struct dom_sid *entry_sid;
70 entry_sid = samdb_result_dom_sid(mem_ctx, (*res)[i], "objectSid");
72 if ((entry_sid == NULL) ||
73 (!dom_sid_in_domain(domain_sid, entry_sid))) {
74 /* Delete that entry from the result set */
75 (*res)[i] = (*res)[count-1];
77 talloc_free(entry_sid);
80 talloc_free(entry_sid);
88 search the sam for a single string attribute in exactly 1 record
90 const char *samdb_search_string_v(struct ldb_context *sam_ldb,
92 const struct ldb_dn *basedn,
93 const char *attr_name,
94 const char *format, va_list ap) _PRINTF_ATTRIBUTE(5,0)
97 const char *attrs[2] = { NULL, NULL };
98 struct ldb_message **res = NULL;
100 attrs[0] = attr_name;
102 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
104 DEBUG(1,("samdb: search for %s %s not single valued (count=%d)\n",
105 attr_name, format, count));
112 return samdb_result_string(res[0], attr_name, NULL);
117 search the sam for a single string attribute in exactly 1 record
119 const char *samdb_search_string(struct ldb_context *sam_ldb,
121 const struct ldb_dn *basedn,
122 const char *attr_name,
123 const char *format, ...) _PRINTF_ATTRIBUTE(5,6)
128 va_start(ap, format);
129 str = samdb_search_string_v(sam_ldb, mem_ctx, basedn, attr_name, format, ap);
135 struct ldb_dn *samdb_search_dn(struct ldb_context *sam_ldb,
137 const struct ldb_dn *basedn,
138 const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
142 struct ldb_message **res = NULL;
145 va_start(ap, format);
146 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, NULL, format, ap);
149 if (count != 1) return NULL;
151 ret = talloc_steal(mem_ctx, res[0]->dn);
158 search the sam for a dom_sid attribute in exactly 1 record
160 struct dom_sid *samdb_search_dom_sid(struct ldb_context *sam_ldb,
162 const struct ldb_dn *basedn,
163 const char *attr_name,
164 const char *format, ...) _PRINTF_ATTRIBUTE(5,6)
168 struct ldb_message **res;
169 const char *attrs[2] = { NULL, NULL };
172 attrs[0] = attr_name;
174 va_start(ap, format);
175 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
178 DEBUG(1,("samdb: search for %s %s not single valued (count=%d)\n",
179 attr_name, format, count));
185 sid = samdb_result_dom_sid(mem_ctx, res[0], attr_name);
191 return the count of the number of records in the sam matching the query
193 int samdb_search_count(struct ldb_context *sam_ldb,
195 const struct ldb_dn *basedn,
196 const char *format, ...) _PRINTF_ATTRIBUTE(4,5)
199 struct ldb_message **res;
200 const char * const attrs[] = { NULL };
203 va_start(ap, format);
204 ret = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
212 search the sam for a single integer attribute in exactly 1 record
214 uint_t samdb_search_uint(struct ldb_context *sam_ldb,
216 uint_t default_value,
217 const struct ldb_dn *basedn,
218 const char *attr_name,
219 const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
223 struct ldb_message **res;
224 const char *attrs[2] = { NULL, NULL };
226 attrs[0] = attr_name;
228 va_start(ap, format);
229 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
233 return default_value;
236 return samdb_result_uint(res[0], attr_name, default_value);
240 search the sam for a single signed 64 bit integer attribute in exactly 1 record
242 int64_t samdb_search_int64(struct ldb_context *sam_ldb,
244 int64_t default_value,
245 const struct ldb_dn *basedn,
246 const char *attr_name,
247 const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
251 struct ldb_message **res;
252 const char *attrs[2] = { NULL, NULL };
254 attrs[0] = attr_name;
256 va_start(ap, format);
257 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
261 return default_value;
264 return samdb_result_int64(res[0], attr_name, default_value);
268 search the sam for multipe records each giving a single string attribute
269 return the number of matches, or -1 on error
271 int samdb_search_string_multiple(struct ldb_context *sam_ldb,
273 const struct ldb_dn *basedn,
275 const char *attr_name,
276 const char *format, ...) _PRINTF_ATTRIBUTE(6,7)
280 const char *attrs[2] = { NULL, NULL };
281 struct ldb_message **res = NULL;
283 attrs[0] = attr_name;
285 va_start(ap, format);
286 count = gendb_search_v(sam_ldb, mem_ctx, basedn, &res, attrs, format, ap);
293 /* make sure its single valued */
294 for (i=0;i<count;i++) {
295 if (res[i]->num_elements != 1) {
296 DEBUG(1,("samdb: search for %s %s not single valued\n",
303 *strs = talloc_array(mem_ctx, const char *, count+1);
309 for (i=0;i<count;i++) {
310 (*strs)[i] = samdb_result_string(res[i], attr_name, NULL);
312 (*strs)[count] = NULL;
318 pull a uint from a result set.
320 uint_t samdb_result_uint(struct ldb_message *msg, const char *attr, uint_t default_value)
322 return ldb_msg_find_uint(msg, attr, default_value);
326 pull a (signed) int64 from a result set.
328 int64_t samdb_result_int64(struct ldb_message *msg, const char *attr, int64_t default_value)
330 return ldb_msg_find_int64(msg, attr, default_value);
334 pull a string from a result set.
336 const char *samdb_result_string(struct ldb_message *msg, const char *attr,
337 const char *default_value)
339 return ldb_msg_find_string(msg, attr, default_value);
342 struct ldb_dn *samdb_result_dn(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
343 const char *attr, struct ldb_dn *default_value)
345 const char *string = samdb_result_string(msg, attr, NULL);
346 if (string == NULL) return default_value;
347 return ldb_dn_explode(mem_ctx, string);
351 pull a rid from a objectSid in a result set.
353 uint32_t samdb_result_rid_from_sid(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
354 const char *attr, uint32_t default_value)
359 sid = samdb_result_dom_sid(mem_ctx, msg, attr);
361 return default_value;
363 rid = sid->sub_auths[sid->num_auths-1];
369 pull a dom_sid structure from a objectSid in a result set.
371 struct dom_sid *samdb_result_dom_sid(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
374 const struct ldb_val *v;
377 v = ldb_msg_find_ldb_val(msg, attr);
381 sid = talloc(mem_ctx, struct dom_sid);
385 status = ndr_pull_struct_blob(v, sid, sid,
386 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
387 if (!NT_STATUS_IS_OK(status)) {
395 pull a guid structure from a objectGUID in a result set.
397 struct GUID samdb_result_guid(struct ldb_message *msg, const char *attr)
399 const struct ldb_val *v;
406 v = ldb_msg_find_ldb_val(msg, attr);
409 mem_ctx = talloc_named_const(NULL, 0, "samdb_result_guid");
410 if (!mem_ctx) return guid;
411 status = ndr_pull_struct_blob(v, mem_ctx, &guid,
412 (ndr_pull_flags_fn_t)ndr_pull_GUID);
413 talloc_free(mem_ctx);
414 if (!NT_STATUS_IS_OK(status)) {
422 pull a sid prefix from a objectSid in a result set.
423 this is used to find the domain sid for a user
425 struct dom_sid *samdb_result_sid_prefix(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
428 struct dom_sid *sid = samdb_result_dom_sid(mem_ctx, msg, attr);
429 if (!sid || sid->num_auths < 1) return NULL;
435 pull a NTTIME in a result set.
437 NTTIME samdb_result_nttime(struct ldb_message *msg, const char *attr, NTTIME default_value)
439 const char *str = ldb_msg_find_string(msg, attr, NULL);
440 if (!str) return default_value;
441 return nttime_from_string(str);
445 pull a uint64_t from a result set.
447 uint64_t samdb_result_uint64(struct ldb_message *msg, const char *attr, uint64_t default_value)
449 return ldb_msg_find_uint64(msg, attr, default_value);
454 construct the allow_password_change field from the PwdLastSet attribute and the
455 domain password settings
457 NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb,
459 const struct ldb_dn *domain_dn,
460 struct ldb_message *msg,
463 uint64_t attr_time = samdb_result_uint64(msg, attr, 0);
466 if (attr_time == 0) {
470 minPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0,
471 domain_dn, "minPwdAge", "dn=%s", ldb_dn_linearize(mem_ctx, domain_dn));
473 /* yes, this is a -= not a += as minPwdAge is stored as the negative
474 of the number of 100-nano-seconds */
475 attr_time -= minPwdAge;
481 construct the force_password_change field from the PwdLastSet attribute and the
482 domain password settings
484 NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
486 const struct ldb_dn *domain_dn,
487 struct ldb_message *msg,
490 uint64_t attr_time = samdb_result_uint64(msg, attr, 0);
493 if (attr_time == 0) {
497 maxPwdAge = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn,
498 "maxPwdAge", "dn=%s", ldb_dn_linearize(mem_ctx, domain_dn));
499 if (maxPwdAge == 0) {
502 attr_time -= maxPwdAge;
509 pull a samr_Password structutre from a result set.
511 struct samr_Password samdb_result_hash(struct ldb_message *msg, const char *attr)
513 struct samr_Password hash;
514 const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
517 memcpy(hash.hash, val->data, MIN(val->length, sizeof(hash.hash)));
523 pull an array of samr_Password structutres from a result set.
525 uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
526 const char *attr, struct samr_Password **hashes)
529 const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
536 count = val->length / 16;
541 *hashes = talloc_array(mem_ctx, struct samr_Password, count);
546 for (i=0;i<count;i++) {
547 memcpy((*hashes)[i].hash, (i*16)+(char *)val->data, 16);
553 NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
554 struct samr_Password **lm_pwd, struct samr_Password **nt_pwd)
557 const char *unicodePwd = samdb_result_string(msg, "unicodePwd", NULL);
559 struct samr_Password *lmPwdHash, *ntPwdHash;
562 ntPwdHash = talloc(mem_ctx, struct samr_Password);
564 return NT_STATUS_NO_MEMORY;
567 E_md4hash(unicodePwd, ntPwdHash->hash);
574 lmPwdHash = talloc(mem_ctx, struct samr_Password);
576 return NT_STATUS_NO_MEMORY;
579 /* compute the new nt and lm hashes */
580 lm_hash_ok = E_deshash(unicodePwd, lmPwdHash->hash);
591 num_nt = samdb_result_hashes(mem_ctx, msg, "ntPwdHash", &ntPwdHash);
594 } else if (num_nt > 1) {
595 return NT_STATUS_INTERNAL_DB_CORRUPTION;
597 *nt_pwd = &ntPwdHash[0];
602 num_lm = samdb_result_hashes(mem_ctx, msg, "lmPwdHash", &lmPwdHash);
605 } else if (num_lm > 1) {
606 return NT_STATUS_INTERNAL_DB_CORRUPTION;
608 *lm_pwd = &lmPwdHash[0];
617 pull a samr_LogonHours structutre from a result set.
619 struct samr_LogonHours samdb_result_logon_hours(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr)
621 struct samr_LogonHours hours;
622 const int units_per_week = 168;
623 const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
625 hours.bits = talloc_array(mem_ctx, uint8_t, units_per_week);
629 hours.units_per_week = units_per_week;
630 memset(hours.bits, 0xFF, units_per_week);
632 memcpy(hours.bits, val->data, MIN(val->length, units_per_week));
638 pull a set of account_flags from a result set.
640 uint16_t samdb_result_acct_flags(struct ldb_message *msg, const char *attr)
642 uint_t userAccountControl = ldb_msg_find_uint(msg, attr, 0);
643 return samdb_uf2acb(userAccountControl);
647 copy from a template record to a message
649 int samdb_copy_template(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
650 struct ldb_message *msg, const char *expression)
652 struct ldb_message **res, *t;
656 /* pull the template record */
657 ret = gendb_search(sam_ldb, mem_ctx, NULL, &res, NULL, "%s", expression);
659 DEBUG(1,("samdb: ERROR: template '%s' matched %d records\n",
665 for (i=0;i<t->num_elements;i++) {
666 struct ldb_message_element *el = &t->elements[i];
667 /* some elements should not be copied from the template */
668 if (strcasecmp(el->name, "cn") == 0 ||
669 strcasecmp(el->name, "name") == 0 ||
670 strcasecmp(el->name, "sAMAccountName") == 0) {
673 for (j=0;j<el->num_values;j++) {
674 if (strcasecmp(el->name, "objectClass") == 0 &&
675 (strcasecmp((char *)el->values[j].data, "Template") == 0 ||
676 strcasecmp((char *)el->values[j].data, "userTemplate") == 0 ||
677 strcasecmp((char *)el->values[j].data, "groupTemplate") == 0 ||
678 strcasecmp((char *)el->values[j].data, "foreignSecurityTemplate") == 0 ||
679 strcasecmp((char *)el->values[j].data, "aliasTemplate") == 0 ||
680 strcasecmp((char *)el->values[j].data, "trustedDomainTemplate") == 0 ||
681 strcasecmp((char *)el->values[j].data, "secretTemplate") == 0)) {
684 samdb_msg_add_string(sam_ldb, mem_ctx, msg, el->name,
685 (char *)el->values[j].data);
694 add a string element to a message
696 int samdb_msg_add_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
697 const char *attr_name, const char *str)
699 char *s = talloc_strdup(mem_ctx, str);
700 char *a = talloc_strdup(mem_ctx, attr_name);
701 if (s == NULL || a == NULL) {
704 return ldb_msg_add_string(sam_ldb, msg, a, s);
708 add a dom_sid element to a message
710 int samdb_msg_add_dom_sid(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
711 const char *attr_name, struct dom_sid *sid)
715 status = ndr_push_struct_blob(&v, mem_ctx, sid,
716 (ndr_push_flags_fn_t)ndr_push_dom_sid);
717 if (!NT_STATUS_IS_OK(status)) {
720 return ldb_msg_add_value(sam_ldb, msg, attr_name, &v);
725 add a delete element operation to a message
727 int samdb_msg_add_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
728 const char *attr_name)
730 char *a = talloc_strdup(mem_ctx, attr_name);
734 /* we use an empty replace rather than a delete, as it allows for
735 samdb_replace() to be used everywhere */
736 return ldb_msg_add_empty(sam_ldb, msg, a, LDB_FLAG_MOD_REPLACE);
740 add a add attribute value to a message
742 int samdb_msg_add_addval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
743 const char *attr_name, const char *value)
745 struct ldb_message_element *el;
748 a = talloc_strdup(mem_ctx, attr_name);
751 v = talloc_strdup(mem_ctx, value);
754 ret = ldb_msg_add_string(sam_ldb, msg, a, v);
757 el = ldb_msg_find_element(msg, a);
760 el->flags = LDB_FLAG_MOD_ADD;
765 add a delete attribute value to a message
767 int samdb_msg_add_delval(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
768 const char *attr_name, const char *value)
770 struct ldb_message_element *el;
773 a = talloc_strdup(mem_ctx, attr_name);
776 v = talloc_strdup(mem_ctx, value);
779 ret = ldb_msg_add_string(sam_ldb, msg, a, v);
782 el = ldb_msg_find_element(msg, a);
785 el->flags = LDB_FLAG_MOD_DELETE;
790 add a uint_t element to a message
792 int samdb_msg_add_uint(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
793 const char *attr_name, uint_t v)
795 const char *s = talloc_asprintf(mem_ctx, "%u", v);
796 return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);
800 add a (signed) int64_t element to a message
802 int samdb_msg_add_int64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
803 const char *attr_name, int64_t v)
805 const char *s = talloc_asprintf(mem_ctx, "%lld", v);
806 return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);
810 add a uint64_t element to a message
812 int samdb_msg_add_uint64(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
813 const char *attr_name, uint64_t v)
815 const char *s = talloc_asprintf(mem_ctx, "%llu", v);
816 return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, s);
820 add a samr_Password element to a message
822 int samdb_msg_add_hash(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
823 const char *attr_name, struct samr_Password *hash)
826 val.data = talloc_memdup(mem_ctx, hash->hash, 16);
831 return ldb_msg_add_value(sam_ldb, msg, attr_name, &val);
835 add a samr_Password array to a message
837 int samdb_msg_add_hashes(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
838 const char *attr_name, struct samr_Password *hashes, uint_t count)
842 val.data = talloc_array_size(mem_ctx, 16, count);
843 val.length = count*16;
847 for (i=0;i<count;i++) {
848 memcpy(i*16 + (char *)val.data, hashes[i].hash, 16);
850 return ldb_msg_add_value(sam_ldb, msg, attr_name, &val);
854 add a acct_flags element to a message
856 int samdb_msg_add_acct_flags(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
857 const char *attr_name, uint32_t v)
859 return samdb_msg_add_uint(sam_ldb, mem_ctx, msg, attr_name, samdb_acb2uf(v));
863 add a logon_hours element to a message
865 int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
866 const char *attr_name, struct samr_LogonHours *hours)
869 val.length = hours->units_per_week / 8;
870 val.data = hours->bits;
871 return ldb_msg_add_value(sam_ldb, msg, attr_name, &val);
875 add a general value element to a message
877 int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
878 const char *attr_name, const struct ldb_val *val)
880 return ldb_msg_add_value(sam_ldb, msg, attr_name, val);
884 sets a general value element to a message
886 int samdb_msg_set_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
887 const char *attr_name, const struct ldb_val *val)
889 struct ldb_message_element *el;
891 el = ldb_msg_find_element(msg, attr_name);
895 return ldb_msg_add_value(sam_ldb, msg, attr_name, val);
899 set a string element in a message
901 int samdb_msg_set_string(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
902 const char *attr_name, const char *str)
904 struct ldb_message_element *el;
906 el = ldb_msg_find_element(msg, attr_name);
910 return samdb_msg_add_string(sam_ldb, mem_ctx, msg, attr_name, str);
914 set a ldaptime element in a message
916 int samdb_msg_set_ldaptime(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
917 const char *attr_name, time_t t)
919 char *str = ldap_timestring(mem_ctx, t);
923 return samdb_msg_set_string(sam_ldb, mem_ctx, msg, attr_name, str);
929 int samdb_add(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg)
931 return ldb_add(sam_ldb, msg);
937 int samdb_delete(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, const struct ldb_dn *dn)
939 return ldb_delete(sam_ldb, dn);
945 int samdb_modify(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg)
947 return ldb_modify(sam_ldb, msg);
951 replace elements in a record
953 int samdb_replace(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg)
957 /* mark all the message elements as LDB_FLAG_MOD_REPLACE */
958 for (i=0;i<msg->num_elements;i++) {
959 msg->elements[i].flags = LDB_FLAG_MOD_REPLACE;
962 /* modify the samdb record */
963 return samdb_modify(sam_ldb, mem_ctx, msg);
967 return a default security descriptor
969 struct security_descriptor *samdb_default_security_descriptor(TALLOC_CTX *mem_ctx)
971 struct security_descriptor *sd;
973 sd = security_descriptor_initialise(mem_ctx);
978 struct ldb_dn *samdb_base_dn(TALLOC_CTX *mem_ctx)
980 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
981 int server_role = lp_server_role();
982 const char **split_realm;
989 if ((server_role == ROLE_DOMAIN_PDC)
990 || (server_role == ROLE_DOMAIN_BDC)) {
992 split_realm = str_list_make(tmp_ctx, lp_realm(), ".");
994 talloc_free(tmp_ctx);
998 i = str_list_length(split_realm);
1000 for (; i >= 0; i--) {
1001 dn = ldb_dn_build_child(tmp_ctx, "dc", split_realm[i], dn);
1003 talloc_free(tmp_ctx);
1009 return ldb_dn_string_compose(mem_ctx, NULL, "cn=%s", lp_netbios_name());