Machines are people too!
[Samba.git] / source / nsswitch / winbindd_util.c
blob18946652e265ec4f95fdfafe448eb81adb8f8705
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind daemon for ntdom nss module
6 Copyright (C) Tim Potter 2000-2001
7 Copyright (C) 2001 by Martin Pool <mbp@samba.org>
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "includes.h"
25 #include "winbindd.h"
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_WINBIND
30 /**
31 * @file winbindd_util.c
33 * Winbind daemon for NT domain authentication nss module.
34 **/
37 /**
38 * Used to clobber name fields that have an undefined value.
40 * Correct code should never look at a field that has this value.
41 **/
43 static const fstring name_deadbeef = "<deadbeef>";
45 /* The list of trusted domains. Note that the list can be deleted and
46 recreated using the init_domain_list() function so pointers to
47 individual winbindd_domain structures cannot be made. Keep a copy of
48 the domain name instead. */
50 static struct winbindd_domain *_domain_list;
52 struct winbindd_domain *domain_list(void)
54 /* Initialise list */
56 if (!_domain_list)
57 if (!init_domain_list())
58 return NULL;
60 return _domain_list;
63 /* Free all entries in the trusted domain list */
65 void free_domain_list(void)
67 struct winbindd_domain *domain = _domain_list;
69 while(domain) {
70 struct winbindd_domain *next = domain->next;
72 DLIST_REMOVE(_domain_list, domain);
73 SAFE_FREE(domain);
74 domain = next;
79 /* Add a trusted domain to our list of domains */
80 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name,
81 struct winbindd_methods *methods,
82 DOM_SID *sid)
84 struct winbindd_domain *domain;
85 const char *alternative_name = NULL;
87 /* ignore alt_name if we are not in an AD domain */
89 if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {
90 alternative_name = alt_name;
93 /* We can't call domain_list() as this function is called from
94 init_domain_list() and we'll get stuck in a loop. */
95 for (domain = _domain_list; domain; domain = domain->next) {
96 if (strequal(domain_name, domain->name) ||
97 strequal(domain_name, domain->alt_name)) {
98 return domain;
100 if (alternative_name && *alternative_name) {
101 if (strequal(alternative_name, domain->name) ||
102 strequal(alternative_name, domain->alt_name)) {
103 return domain;
108 /* Create new domain entry */
110 if ((domain = (struct winbindd_domain *)
111 malloc(sizeof(*domain))) == NULL)
112 return NULL;
114 /* Fill in fields */
116 ZERO_STRUCTP(domain);
118 /* prioritise the short name */
119 if (strchr_m(domain_name, '.') && alternative_name && *alternative_name) {
120 fstrcpy(domain->name, alternative_name);
121 fstrcpy(domain->alt_name, domain_name);
122 } else {
123 fstrcpy(domain->name, domain_name);
124 if (alternative_name) {
125 fstrcpy(domain->alt_name, alternative_name);
129 domain->methods = methods;
130 domain->backend = NULL;
131 domain->sequence_number = DOM_SEQUENCE_NONE;
132 domain->last_seq_check = 0;
133 if (sid) {
134 sid_copy(&domain->sid, sid);
137 /* see if this is a native mode win2k domain */
139 domain->native_mode = cm_check_for_native_mode_win2k( domain );
141 DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name,
142 domain->native_mode ? "native" : "mixed (or NT4)" ));
144 /* Link to domain list */
145 DLIST_ADD(_domain_list, domain);
147 DEBUG(1,("Added domain %s %s %s\n",
148 domain->name, domain->alt_name,
149 sid?sid_string_static(&domain->sid):""));
151 return domain;
154 /********************************************************************
155 Periodically we need to refresh the trusted domain cache for smbd
156 ********************************************************************/
158 void rescan_trusted_domains( void )
160 static time_t last_scan;
161 time_t now = time(NULL);
162 struct winbindd_domain *mydomain = NULL;
164 /* see if the time has come... */
166 if ( (now > last_scan) && ((now-last_scan) < WINBINDD_RESCAN_FREQ) )
167 return;
169 if ( (mydomain = find_our_domain()) == NULL ) {
170 DEBUG(0,("rescan_trusted_domains: Can't find my own domain!\n"));
171 return;
174 /* this will only add new domains we didn't already know about */
176 add_trusted_domains( mydomain );
178 last_scan = now;
180 return;
183 /********************************************************************
184 rescan our domains looking for new trusted domains
185 ********************************************************************/
187 void add_trusted_domains( struct winbindd_domain *domain )
189 TALLOC_CTX *mem_ctx;
190 NTSTATUS result;
191 time_t t;
192 char **names;
193 char **alt_names;
194 int num_domains = 0;
195 DOM_SID *dom_sids, null_sid;
196 int i;
197 struct winbindd_domain *new_domain;
199 /* trusted domains might be disabled */
200 if (!lp_allow_trusted_domains()) {
201 return;
204 DEBUG(5, ("scanning trusted domain list\n"));
206 if (!(mem_ctx = talloc_init("init_domain_list")))
207 return;
209 ZERO_STRUCTP(&null_sid);
211 t = time(NULL);
213 /* ask the DC what domains it trusts */
215 result = domain->methods->trusted_domains(domain, mem_ctx, (unsigned int *)&num_domains,
216 &names, &alt_names, &dom_sids);
218 if ( NT_STATUS_IS_OK(result) ) {
220 /* Add each domain to the trusted domain list */
222 for(i = 0; i < num_domains; i++) {
223 DEBUG(10,("Found domain %s\n", names[i]));
224 add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
225 domain->methods, &dom_sids[i]);
227 /* if the SID was empty, we better set it now */
229 if ( sid_equal(&dom_sids[i], &null_sid) ) {
231 new_domain = find_domain_from_name(names[i]);
233 /* this should never happen */
234 if ( !new_domain ) {
235 DEBUG(0,("rescan_trust_domains: can't find the domain I just added! [%s]\n",
236 names[i]));
237 break;
240 /* call the cache method; which will operate on the winbindd_domain \
241 passed in and choose either rpc or ads as appropriate */
243 result = domain->methods->domain_sid( new_domain, &new_domain->sid );
245 if ( NT_STATUS_IS_OK(result) )
246 sid_copy( &dom_sids[i], &new_domain->sid );
249 /* store trusted domain in the cache */
250 trustdom_cache_store(names[i], alt_names ? alt_names[i] : NULL,
251 &dom_sids[i], t + WINBINDD_RESCAN_FREQ);
255 talloc_destroy(mem_ctx);
258 /* Look up global info for the winbind daemon */
259 BOOL init_domain_list(void)
261 extern struct winbindd_methods cache_methods;
262 struct winbindd_domain *domain;
264 /* Free existing list */
265 free_domain_list();
267 /* Add ourselves as the first entry. It *must* be the first entry */
269 domain = add_trusted_domain( lp_workgroup(), lp_realm(), &cache_methods, NULL);
271 domain->primary = True;
273 /* get any alternate name for the primary domain */
275 cache_methods.alternate_name(domain);
277 /* now we have the correct netbios (short) domain name */
279 if ( *domain->name )
280 set_global_myworkgroup( domain->name );
282 if (!secrets_fetch_domain_sid(domain->name, &domain->sid)) {
283 DEBUG(1, ("Could not fetch sid for our domain %s\n",
284 domain->name));
285 return False;
288 /* do an initial scan for trusted domains */
289 add_trusted_domains(domain);
291 return True;
294 /**
295 * Given a domain name, return the struct winbindd domain info for it
297 * @note Do *not* pass lp_workgroup() to this function. domain_list
298 * may modify it's value, and free that pointer. Instead, our local
299 * domain may be found by calling find_our_domain().
300 * directly.
303 * @return The domain structure for the named domain, if it is working.
306 struct winbindd_domain *find_domain_from_name(const char *domain_name)
308 struct winbindd_domain *domain;
310 /* Search through list */
312 for (domain = domain_list(); domain != NULL; domain = domain->next) {
313 if (strequal(domain_name, domain->name) ||
314 (domain->alt_name[0] && strequal(domain_name, domain->alt_name))) {
315 return domain;
319 /* Not found */
321 return NULL;
324 /* Given a domain sid, return the struct winbindd domain info for it */
326 struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
328 struct winbindd_domain *domain;
330 /* Search through list */
332 for (domain = domain_list(); domain != NULL; domain = domain->next) {
333 if (sid_compare_domain(sid, &domain->sid) == 0)
334 return domain;
337 /* Not found */
339 return NULL;
342 /* Given a domain sid, return the struct winbindd domain info for it */
344 struct winbindd_domain *find_our_domain(void)
346 struct winbindd_domain *domain;
348 /* Search through list */
350 for (domain = domain_list(); domain != NULL; domain = domain->next) {
351 if (domain->primary)
352 return domain;
355 /* Not found */
357 return NULL;
360 /* Lookup a sid in a domain from a name */
362 BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
363 const char *name, DOM_SID *sid,
364 enum SID_NAME_USE *type)
366 NTSTATUS result;
367 TALLOC_CTX *mem_ctx;
369 mem_ctx = talloc_init("lookup_sid_by_name for %s\n", name);
370 if (!mem_ctx)
371 return False;
373 /* Lookup name */
374 result = domain->methods->name_to_sid(domain, mem_ctx, name, sid, type);
376 talloc_destroy(mem_ctx);
378 /* Return rid and type if lookup successful */
379 if (!NT_STATUS_IS_OK(result)) {
380 *type = SID_NAME_UNKNOWN;
383 return NT_STATUS_IS_OK(result);
387 * @brief Lookup a name in a domain from a sid.
389 * @param sid Security ID you want to look up.
390 * @param name On success, set to the name corresponding to @p sid.
391 * @param dom_name On success, set to the 'domain name' corresponding to @p sid.
392 * @param type On success, contains the type of name: alias, group or
393 * user.
394 * @retval True if the name exists, in which case @p name and @p type
395 * are set, otherwise False.
397 BOOL winbindd_lookup_name_by_sid(DOM_SID *sid,
398 fstring dom_name,
399 fstring name,
400 enum SID_NAME_USE *type)
402 char *names;
403 NTSTATUS result;
404 TALLOC_CTX *mem_ctx;
405 BOOL rv = False;
406 struct winbindd_domain *domain;
408 domain = find_domain_from_sid(sid);
410 if (!domain) {
411 DEBUG(1,("Can't find domain from sid\n"));
412 return False;
415 /* Lookup name */
417 if (!(mem_ctx = talloc_init("winbindd_lookup_name_by_sid")))
418 return False;
420 result = domain->methods->sid_to_name(domain, mem_ctx, sid, &names, type);
422 /* Return name and type if successful */
424 if ((rv = NT_STATUS_IS_OK(result))) {
425 fstrcpy(dom_name, domain->name);
426 fstrcpy(name, names);
427 } else {
428 *type = SID_NAME_UNKNOWN;
429 fstrcpy(name, name_deadbeef);
432 talloc_destroy(mem_ctx);
434 return rv;
438 /* Free state information held for {set,get,end}{pw,gr}ent() functions */
440 void free_getent_state(struct getent_state *state)
442 struct getent_state *temp;
444 /* Iterate over state list */
446 temp = state;
448 while(temp != NULL) {
449 struct getent_state *next;
451 /* Free sam entries then list entry */
453 SAFE_FREE(state->sam_entries);
454 DLIST_REMOVE(state, state);
455 next = temp->next;
457 SAFE_FREE(temp);
458 temp = next;
462 /* Parse winbindd related parameters */
464 BOOL winbindd_param_init(void)
466 /* Parse winbind uid and winbind_gid parameters */
468 if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) {
469 DEBUG(0, ("winbindd: idmap uid range missing or invalid\n"));
470 DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
471 return False;
474 if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) {
475 DEBUG(0, ("winbindd: idmap gid range missing or invalid\n"));
476 DEBUG(0, ("winbindd: cannot continue, exiting.\n"));
477 return False;
480 return True;
483 /* Check if a domain is present in a comma-separated list of domains */
485 BOOL check_domain_env(char *domain_env, char *domain)
487 fstring name;
488 const char *tmp = domain_env;
490 while(next_token(&tmp, name, ",", sizeof(fstring))) {
491 if (strequal(name, domain))
492 return True;
495 return False;
498 /* Is this a domain which we may assume no DOMAIN\ prefix? */
500 static BOOL assume_domain(const char *domain) {
501 if ((lp_winbind_use_default_domain()
502 || lp_winbind_trusted_domains_only()) &&
503 strequal(lp_workgroup(), domain))
504 return True;
506 if (strequal(get_global_sam_name(), domain))
507 return True;
509 return False;
512 /* Parse a string of the form DOMAIN/user into a domain and a user */
514 BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
516 char *p = strchr(domuser,*lp_winbind_separator());
518 if ( !p ) {
519 fstrcpy(user, domuser);
521 if ( assume_domain(lp_workgroup())) {
522 fstrcpy(domain, lp_workgroup());
523 } else {
524 fstrcpy( domain, get_global_sam_name() );
527 else {
528 fstrcpy(user, p+1);
529 fstrcpy(domain, domuser);
530 domain[PTR_DIFF(p, domuser)] = 0;
533 strupper_m(domain);
535 return True;
539 Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and
540 'winbind separator' options.
541 This means:
542 - omit DOMAIN when 'winbind use default domain = true' and DOMAIN is
543 lp_workgroup()
545 If we are a PDC or BDC, and this is for our domain, do likewise.
547 Also, if omit DOMAIN if 'winbind trusted domains only = true', as the
548 username is then unqualified in unix
551 void fill_domain_username(fstring name, const char *domain, const char *user)
553 if (assume_domain(domain)) {
554 strlcpy(name, user, sizeof(fstring));
555 } else {
556 slprintf(name, sizeof(fstring) - 1, "%s%s%s",
557 domain, lp_winbind_separator(),
558 user);
563 * Winbindd socket accessor functions
566 char *get_winbind_priv_pipe_dir(void)
568 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
571 /* Open the winbindd socket */
573 static int _winbindd_socket = -1;
574 static int _winbindd_priv_socket = -1;
576 int open_winbindd_socket(void)
578 if (_winbindd_socket == -1) {
579 _winbindd_socket = create_pipe_sock(
580 WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);
581 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
582 _winbindd_socket));
585 return _winbindd_socket;
588 int open_winbindd_priv_socket(void)
590 if (_winbindd_priv_socket == -1) {
591 _winbindd_priv_socket = create_pipe_sock(
592 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
593 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
594 _winbindd_priv_socket));
597 return _winbindd_priv_socket;
600 /* Close the winbindd socket */
602 void close_winbindd_socket(void)
604 if (_winbindd_socket != -1) {
605 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
606 _winbindd_socket));
607 close(_winbindd_socket);
608 _winbindd_socket = -1;
610 if (_winbindd_priv_socket != -1) {
611 DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
612 _winbindd_priv_socket));
613 close(_winbindd_priv_socket);
614 _winbindd_priv_socket = -1;
619 * Client list accessor functions
622 static struct winbindd_cli_state *_client_list;
623 static int _num_clients;
625 /* Return list of all connected clients */
627 struct winbindd_cli_state *winbindd_client_list(void)
629 return _client_list;
632 /* Add a connection to the list */
634 void winbindd_add_client(struct winbindd_cli_state *cli)
636 DLIST_ADD(_client_list, cli);
637 _num_clients++;
640 /* Remove a client from the list */
642 void winbindd_remove_client(struct winbindd_cli_state *cli)
644 DLIST_REMOVE(_client_list, cli);
645 _num_clients--;
648 /* Close all open clients */
650 void winbindd_kill_all_clients(void)
652 struct winbindd_cli_state *cl = winbindd_client_list();
654 DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));
656 while (cl) {
657 struct winbindd_cli_state *next;
659 next = cl->next;
660 winbindd_remove_client(cl);
661 cl = next;
665 /* Return number of open clients */
667 int winbindd_num_clients(void)
669 return _num_clients;
672 /* Help with RID -> SID conversion */
674 DOM_SID *rid_to_talloced_sid(struct winbindd_domain *domain,
675 TALLOC_CTX *mem_ctx,
676 uint32 rid)
678 DOM_SID *sid;
679 sid = talloc(mem_ctx, sizeof(*sid));
680 if (!sid) {
681 smb_panic("rid_to_to_talloced_sid: talloc for DOM_SID failed!\n");
683 sid_copy(sid, &domain->sid);
684 sid_append_rid(sid, rid);
685 return sid;
688 /*****************************************************************************
689 For idmap conversion: convert one record to new format
690 Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid
691 instead of the SID.
692 *****************************************************************************/
693 static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state)
695 struct winbindd_domain *domain;
696 char *p;
697 DOM_SID sid;
698 uint32 rid;
699 fstring keystr;
700 fstring dom_name;
701 TDB_DATA key2;
702 BOOL *failed = (BOOL *)state;
704 DEBUG(10,("Converting %s\n", key.dptr));
706 p = strchr(key.dptr, '/');
707 if (!p)
708 return 0;
710 *p = 0;
711 fstrcpy(dom_name, key.dptr);
712 *p++ = '/';
714 domain = find_domain_from_name(dom_name);
715 if (domain == NULL) {
716 /* We must delete the old record. */
717 DEBUG(0,("Unable to find domain %s\n", dom_name ));
718 DEBUG(0,("deleting record %s\n", key.dptr ));
720 if (tdb_delete(tdb, key) != 0) {
721 DEBUG(0, ("Unable to delete record %s\n", key.dptr));
722 *failed = True;
723 return -1;
726 return 0;
729 rid = atoi(p);
731 sid_copy(&sid, &domain->sid);
732 sid_append_rid(&sid, rid);
734 sid_to_string(keystr, &sid);
735 key2.dptr = keystr;
736 key2.dsize = strlen(keystr) + 1;
738 if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) {
739 DEBUG(0,("Unable to add record %s\n", key2.dptr ));
740 *failed = True;
741 return -1;
744 if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) {
745 DEBUG(0,("Unable to update record %s\n", data.dptr ));
746 *failed = True;
747 return -1;
750 if (tdb_delete(tdb, key) != 0) {
751 DEBUG(0,("Unable to delete record %s\n", key.dptr ));
752 *failed = True;
753 return -1;
756 return 0;
759 /* These definitions are from sam/idmap_tdb.c. Replicated here just
760 out of laziness.... :-( */
762 /* High water mark keys */
763 #define HWM_GROUP "GROUP HWM"
764 #define HWM_USER "USER HWM"
766 /* idmap version determines auto-conversion */
767 #define IDMAP_VERSION 2
770 /*****************************************************************************
771 Convert the idmap database from an older version.
772 *****************************************************************************/
774 static BOOL idmap_convert(const char *idmap_name)
776 int32 vers;
777 BOOL bigendianheader;
778 BOOL failed = False;
779 TDB_CONTEXT *idmap_tdb;
781 if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
782 TDB_DEFAULT, O_RDWR,
783 0600))) {
784 DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
785 return False;
788 bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;
790 vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");
792 if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {
793 /* Arrggghh ! Bytereversed or old big-endian - make order independent ! */
795 * high and low records were created on a
796 * big endian machine and will need byte-reversing.
799 int32 wm;
801 wm = tdb_fetch_int32(idmap_tdb, HWM_USER);
803 if (wm != -1) {
804 wm = IREV(wm);
805 } else {
806 wm = server_state.uid_low;
809 if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {
810 DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n"));
811 tdb_close(idmap_tdb);
812 return False;
815 wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);
816 if (wm != -1) {
817 wm = IREV(wm);
818 } else {
819 wm = server_state.gid_low;
822 if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {
823 DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));
824 tdb_close(idmap_tdb);
825 return False;
829 /* the old format stored as DOMAIN/rid - now we store the SID direct */
830 tdb_traverse(idmap_tdb, convert_fn, &failed);
832 if (failed) {
833 DEBUG(0, ("Problem during conversion\n"));
834 tdb_close(idmap_tdb);
835 return False;
838 if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) {
839 DEBUG(0, ("idmap_convert: Unable to dtore idmap version in databse\n"));
840 tdb_close(idmap_tdb);
841 return False;
844 tdb_close(idmap_tdb);
845 return True;
848 /*****************************************************************************
849 Convert the idmap database from an older version if necessary
850 *****************************************************************************/
852 BOOL winbindd_upgrade_idmap(void)
854 pstring idmap_name;
855 pstring backup_name;
856 SMB_STRUCT_STAT stbuf;
857 TDB_CONTEXT *idmap_tdb;
859 pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb"));
861 if (!file_exist(idmap_name, &stbuf)) {
862 /* nothing to convert return */
863 return True;
866 if (!(idmap_tdb = tdb_open_log(idmap_name, 0,
867 TDB_DEFAULT, O_RDWR,
868 0600))) {
869 DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));
870 return False;
873 if (tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION") == IDMAP_VERSION) {
874 /* nothing to convert return */
875 tdb_close(idmap_tdb);
876 return True;
879 /* backup_tdb expects the tdb not to be open */
880 tdb_close(idmap_tdb);
882 DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));
884 pstrcpy(backup_name, idmap_name);
885 pstrcat(backup_name, ".bak");
887 if (backup_tdb(idmap_name, backup_name) != 0) {
888 DEBUG(0, ("Could not backup idmap database\n"));
889 return False;
892 return idmap_convert(idmap_name);
895 /*******************************************************************
896 wrapper around retrieving the trust account password
897 *******************************************************************/
899 BOOL get_trust_pw(const char *domain, uint8 ret_pwd[16],
900 time_t *pass_last_set_time, uint32 *channel)
902 DOM_SID sid;
903 char *pwd;
905 /* if we are a DC and this is not our domain, then lookup an account
906 for the domain trust */
908 if ( IS_DC && !strequal(domain, lp_workgroup()) && lp_allow_trusted_domains() )
910 if ( !secrets_fetch_trusted_domain_password(domain, &pwd, &sid,
911 pass_last_set_time) )
913 DEBUG(0, ("get_trust_pw: could not fetch trust account "
914 "password for trusted domain %s\n", domain));
915 return False;
918 *channel = SEC_CHAN_DOMAIN;
919 E_md4hash(pwd, ret_pwd);
920 SAFE_FREE(pwd);
922 return True;
924 else /* just get the account for our domain (covers
925 ROLE_DOMAIN_MEMBER as well */
927 /* get the machine trust account for our domain */
929 if ( !secrets_fetch_trust_account_password (lp_workgroup(), ret_pwd,
930 pass_last_set_time, channel) )
932 DEBUG(0, ("get_trust_pw: could not fetch trust account "
933 "password for my domain %s\n", domain));
934 return False;
937 return True;
940 /* Failure */