summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_util.c')
-rw-r--r--source3/nsswitch/winbindd_util.c145
1 files changed, 90 insertions, 55 deletions
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 3086795a49..f90e89c23f 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -36,53 +36,39 @@
*
* Correct code should never look at a field that has this value.
**/
+
static const fstring name_deadbeef = "<deadbeef>";
+/* The list of trusted domains. Note that the list can be deleted and
+ recreated using the init_domain_list() function so pointers to
+ individual winbindd_domain structures cannot be made. Keep a copy of
+ the domain name instead. */
-/* Globals for domain list stuff */
-struct winbindd_domain *domain_list = NULL;
+static struct winbindd_domain *_domain_list;
-/* Given a domain name, return the struct winbindd domain info for it
- if it is actually working. */
-
-struct winbindd_domain *find_domain_from_name(char *domain_name)
+struct winbindd_domain *domain_list(void)
{
- struct winbindd_domain *domain;
-
- if (domain_list == NULL)
- get_domain_info();
+ /* Initialise list */
- /* Search through list */
+ if (!_domain_list)
+ init_domain_list();
- for (domain = domain_list; domain != NULL; domain = domain->next) {
- if (strcasecmp(domain_name, domain->name) == 0 ||
- strcasecmp(domain_name, domain->full_name) == 0)
- return domain;
- }
-
- /* Not found */
-
- return NULL;
+ return _domain_list;
}
-/* Given a domain sid, return the struct winbindd domain info for it */
+/* Free all entries in the trusted domain list */
-struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
+void free_domain_list(void)
{
- struct winbindd_domain *domain;
-
- if (domain_list == NULL)
- get_domain_info();
-
- /* Search through list */
- for (domain = domain_list; domain != NULL; domain = domain->next) {
- if (sid_compare_domain(sid, &domain->sid) == 0)
- return domain;
+ struct winbindd_domain *domain = _domain_list;
+
+ while(domain) {
+ struct winbindd_domain *next = domain->next;
+
+ DLIST_REMOVE(_domain_list, domain);
+ SAFE_FREE(domain);
+ domain = next;
}
-
- /* Not found */
-
- return NULL;
}
/* Add a trusted domain to our list of domains */
@@ -92,7 +78,10 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
{
struct winbindd_domain *domain;
- for (domain = domain_list; domain; domain = domain->next) {
+ /* We can't call domain_list() as this function is called from
+ init_domain_list() and we'll get stuck in a loop. */
+
+ for (domain = _domain_list; domain; domain = domain->next) {
if (strcmp(domain_name, domain->name) == 0) {
DEBUG(3, ("domain %s already in domain list\n",
domain_name));
@@ -117,14 +106,14 @@ static struct winbindd_domain *add_trusted_domain(char *domain_name,
/* Link to domain list */
- DLIST_ADD(domain_list, domain);
+ DLIST_ADD(_domain_list, domain);
return domain;
}
/* Look up global info for the winbind daemon */
-BOOL get_domain_info(void)
+BOOL init_domain_list(void)
{
NTSTATUS result;
TALLOC_CTX *mem_ctx;
@@ -134,13 +123,20 @@ BOOL get_domain_info(void)
char **names;
int num_domains = 0;
- if (!(mem_ctx = talloc_init_named("get_domain_info")))
+ if (!(mem_ctx = talloc_init_named("init_domain_list")))
return False;
+ /* Free existing list */
+
+ free_domain_list();
+
+ /* Add ourselves as the first entry */
+
domain = add_trusted_domain(lp_workgroup(), &cache_methods);
- /* now we *must* get the domain sid for our primary domain. Go into a holding
- pattern until that is available */
+ /* Now we *must* get the domain sid for our primary domain. Go into
+ a holding pattern until that is available */
+
result = cache_methods.domain_sid(domain, &domain->sid);
while (!NT_STATUS_IS_OK(result)) {
sleep(10);
@@ -179,10 +175,49 @@ BOOL get_domain_info(void)
return True;
}
+/* Given a domain name, return the struct winbindd domain info for it
+ if it is actually working. */
+
+struct winbindd_domain *find_domain_from_name(char *domain_name)
+{
+ struct winbindd_domain *domain;
+
+ /* Search through list */
+
+ for (domain = domain_list(); domain != NULL; domain = domain->next) {
+ if (strequal(domain_name, domain->name) ||
+ strequal(domain_name, domain->full_name))
+ return domain;
+ }
+
+ /* Not found */
+
+ return NULL;
+}
+
+/* Given a domain sid, return the struct winbindd domain info for it */
+
+struct winbindd_domain *find_domain_from_sid(DOM_SID *sid)
+{
+ struct winbindd_domain *domain;
+
+ /* Search through list */
+
+ for (domain = domain_list(); domain != NULL; domain = domain->next) {
+ if (sid_compare_domain(sid, &domain->sid) == 0)
+ return domain;
+ }
+
+ /* Not found */
+
+ return NULL;
+}
/* Lookup a sid in a domain from a name */
+
BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
- const char *name, DOM_SID *sid, enum SID_NAME_USE *type)
+ const char *name, DOM_SID *sid,
+ enum SID_NAME_USE *type)
{
NTSTATUS result;
@@ -282,19 +317,19 @@ void free_getent_state(struct getent_state *state)
BOOL winbindd_param_init(void)
{
- /* Parse winbind uid and winbind_gid parameters */
-
- if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
- DEBUG(0, ("winbind uid range missing or invalid\n"));
- return False;
- }
-
- if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
- DEBUG(0, ("winbind gid range missing or invalid\n"));
- return False;
- }
-
- return True;
+ /* Parse winbind uid and winbind_gid parameters */
+
+ if (!lp_winbind_uid(&server_state.uid_low, &server_state.uid_high)) {
+ DEBUG(0, ("winbind uid range missing or invalid\n"));
+ return False;
+ }
+
+ if (!lp_winbind_gid(&server_state.gid_low, &server_state.gid_high)) {
+ DEBUG(0, ("winbind gid range missing or invalid\n"));
+ return False;
+ }
+
+ return True;
}
/* Check if a domain is present in a comma-separated list of domains */