summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2000-04-23 00:21:19 +0000
committerTim Potter <tpot@samba.org>2000-04-23 00:21:19 +0000
commit0e02b02287d01a70d7fc24a13592bc0f76a17770 (patch)
treeb653a425644005bf1fa31b5d9a3aacabb8d3afcb
parent79ad281402e7020352ef775cac5ca215d86ea062 (diff)
downloadsamba-0e02b02287d01a70d7fc24a13592bc0f76a17770.tar.gz
samba-0e02b02287d01a70d7fc24a13592bc0f76a17770.tar.xz
samba-0e02b02287d01a70d7fc24a13592bc0f76a17770.zip
Major work on architecture of nss client, winbindd and NT server
communications. Client state now indexed by file descriptor rather than pid number closing a possible security hole. The lsa and samr pipe handles now cached on a per-domain basis which speeds things up dramatically. However it has exposed some problems in the rpc client code. Use and group enumeration code and types simplified quite a bit. Still some work to do in moving yet more state back towards the nss client. The eventual goal is to have nss clients unaffected by the stopping and restarting of the winbind daemon. Some scalability issues still to be addressed.
-rw-r--r--source/nsswitch/winbind_nss.c10
-rw-r--r--source/nsswitch/winbindd.c39
-rw-r--r--source/nsswitch/winbindd_group.c196
-rw-r--r--source/nsswitch/winbindd_surs.c270
-rw-r--r--source/nsswitch/winbindd_util.c534
5 files changed, 452 insertions, 597 deletions
diff --git a/source/nsswitch/winbind_nss.c b/source/nsswitch/winbind_nss.c
index 0cea49cf0a0..f41f29a72a5 100644
--- a/source/nsswitch/winbind_nss.c
+++ b/source/nsswitch/winbind_nss.c
@@ -431,6 +431,7 @@ _nss_ntdom_setpwent(void)
/* Fill in request and send down pipe */
request.cmd = WINBINDD_SETPWENT;
+ request.pid = getpid();
if ((result = write_sock(sock, &request, sizeof(request))) == -1) {
close(sock);
@@ -471,6 +472,7 @@ _nss_ntdom_endpwent(void)
/* Fill in request and send down pipe */
request.cmd = WINBINDD_ENDPWENT;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -511,6 +513,7 @@ _nss_ntdom_getpwent_r(struct passwd *result, char *buffer,
/* Fill in request and send down pipe */
request.cmd = WINBINDD_GETPWENT;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
close(sock);
@@ -554,6 +557,7 @@ _nss_ntdom_getpwuid_r(uid_t uid, struct passwd *result, char *buffer,
request.cmd = WINBINDD_GETPWNAM_FROM_UID;
request.data.uid = uid;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -597,6 +601,7 @@ _nss_ntdom_getpwnam_r(const char *name, struct passwd *result, char *buffer,
/* Fill in request and send down pipe */
request.cmd = WINBINDD_GETPWNAM_FROM_USER;
+ request.pid = getpid();
strncpy(request.data.username, name, sizeof(request.data.username) - 1);
request.data.username[sizeof(request.data.username) - 1] = '\0';
@@ -644,6 +649,7 @@ _nss_ntdom_setgrent(void)
/* Fill in request and send down pipe */
request.cmd = WINBINDD_SETGRENT;
+ request.pid = getpid();
if ((result = write_sock(sock, &request, sizeof(request))) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -683,6 +689,7 @@ _nss_ntdom_endgrent(void)
/* Fill in request and send down pipe */
request.cmd = WINBINDD_ENDGRENT;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -723,6 +730,7 @@ _nss_ntdom_getgrent_r(struct group *result,
/* Fill in request and send down pipe */
request.cmd = WINBINDD_GETGRENT;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
return NSS_STATUS_UNAVAIL;
@@ -764,6 +772,7 @@ _nss_ntdom_getgrnam_r(const char *name,
/* Fill in request and send down pipe */
request.cmd = WINBINDD_GETGRNAM_FROM_GROUP;
+ request.pid = getpid();
strncpy(request.data.groupname, name, sizeof(request.data.groupname));
request.data.groupname[sizeof(request.data.groupname) - 1] = '\0';
@@ -809,6 +818,7 @@ _nss_ntdom_getgrgid_r(gid_t gid,
request.cmd = WINBINDD_GETGRNAM_FROM_GID;
request.data.gid = gid;
+ request.pid = getpid();
if (write_sock(sock, &request, sizeof(request)) == -1) {
return NSS_STATUS_UNAVAIL;
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 40485560b2d..9d31f93a4e6 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -33,7 +33,9 @@
static struct winbindd_state *client_list;
-/* Handle termination signals */
+/*
+ * Signal handlers
+ */
static void termination_handler(int signum)
{
@@ -44,6 +46,20 @@ static void termination_handler(int signum)
exit(0);
}
+static BOOL print_client_info;
+
+static void siguser1_handler(int signum)
+{
+ print_client_info = True;
+}
+
+static BOOL flush_cache;
+
+static void sighup_handler(int signum)
+{
+ flush_cache = True;
+}
+
/* Create winbindd socket */
static int create_sock(void)
@@ -149,17 +165,14 @@ static void process_request(struct winbindd_state *state)
break;
case WINBINDD_SETPWENT:
- fprintf(stderr, "calling setpwent()\n");
state->response.result = winbindd_setpwent(state);
break;
case WINBINDD_ENDPWENT:
- fprintf(stderr, "calling endpwent()\n");
state->response.result = winbindd_endpwent(state);
break;
case WINBINDD_GETPWENT:
- fprintf(stderr, "calling getpwent()\n");
state->response.result = winbindd_getpwent(state);
break;
@@ -365,6 +378,18 @@ static void process_loop(int accept_sock)
state = state->next;
}
+ /* Check signal handling */
+
+ if (flush_cache) {
+ fprintf(stderr, "flush cache request\n");
+ flush_cache = False;
+ }
+
+ if (print_client_info) {
+ fprintf(stderr, "print client info requet\n");
+ print_client_info = False;
+ }
+
/* Call select */
fprintf(stderr, "calling select\n");
@@ -374,6 +399,7 @@ static void process_loop(int accept_sock)
/* Select error, something is badly wrong */
+ exit(2);
DEBUG(0, ("select returned %d", selret));
return;
}
@@ -447,8 +473,7 @@ int main(int argc, char **argv)
pwdb_initialise(False);
- if (!winbindd_surs_init()) {
- DEBUG(0, ("Could not initialise surs information\n"));
+ if (!winbindd_param_init()) {
return 1;
}
@@ -458,6 +483,8 @@ int main(int argc, char **argv)
signal(SIGQUIT, termination_handler);
signal(SIGTERM, termination_handler);
signal(SIGPIPE, SIG_IGN);
+ signal(SIGUSR1, siguser1_handler);
+ signal(SIGHUP, sighup_handler);
/* Create UNIX domain socket */
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index d4d977780cf..5ad3168fb9e 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -49,10 +49,9 @@ struct grent_mem_group {
struct grent_mem_group *prev, *next;
};
-static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
+static BOOL winbindd_fill_grent_mem(struct winbindd_domain *domain,
uint32 group_rid,
enum SID_NAME_USE group_name_type,
- POLICY_HND *sam_dom_handle,
struct winbindd_gr *gr)
{
struct grent_mem_group *done_groups = NULL, *todo_groups = NULL;
@@ -71,9 +70,10 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
}
ZERO_STRUCTP(temp);
+
temp->group_rid = group_rid;
temp->group_name_type = group_name_type;
- fstrcpy(temp->domain_name, domain_name);
+ fstrcpy(temp->domain_name, domain->name);
DLIST_ADD(todo_groups, temp);
@@ -81,31 +81,15 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
while(todo_groups != NULL) {
struct grent_mem_group *current_group = todo_groups;
- uint32 num_names = 0, num_sids = 0, *rid_mem = NULL,
- *name_types = NULL;
- DOM_SID **sids = NULL, domain_sid;
- char **names = NULL;
- int i, done_group;
-
- /* Find domain sid for this group */
+ uint32 num_names = 0, num_sids = 0, *rid_mem = NULL;
+ enum SID_NAME_USE *name_types = NULL;
- if (!find_domain_sid_from_name(current_group->domain_name,
- &domain_sid, NULL)) {
- DEBUG(1, ("%s:%d: could not locate domain sid for domain "
- "%s\n", __FUNCTION__, __LINE__,
- current_group->domain_name));
-
- /* Exit if we cannot lookup the sid for the domain of the group
- this function was called to look at */
-
- if (fstrcpy(current_group->domain_name, domain_name) == 0) {
- return False;
- } else {
- goto cleanup;
- }
- }
+ DOM_SID **sids = NULL;
+ char **names = NULL;
+ BOOL done_group;
+ int i;
- /* Check we aren't doing it recursively */
+ /* Check we haven't looked up this group before */
done_group = 0;
@@ -122,10 +106,9 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
/* Lookup group membership for the current group */
if (current_group->group_name_type == SID_NAME_DOM_GRP) {
- if (!winbindd_lookup_groupmem(server_name, &domain_sid,
- current_group->group_rid,
- sam_dom_handle, &num_names,
- &rid_mem, &names, &name_types)) {
+ if (!winbindd_lookup_groupmem(domain, current_group->group_rid,
+ &num_names, &rid_mem, &names,
+ &name_types)) {
DEBUG(1, ("fill_grent_mem(): group rid %d not a domain "
"group\n", current_group->group_rid));
@@ -142,14 +125,9 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
}
if (current_group->group_name_type == SID_NAME_ALIAS) {
- if (!winbindd_lookup_aliasmem(server_name, &domain_sid,
- current_group->group_rid,
- sam_dom_handle, &num_names,
- &sids, &names, &name_types) &&
- !winbindd_lookup_aliasmem(server_name, global_sid_builtin,
- current_group->group_rid,
- sam_dom_handle, &num_sids,
- &sids, &names, &name_types)) {
+ if (!winbindd_lookup_aliasmem(domain, current_group->group_rid,
+ &num_names, &sids, &names,
+ &name_types)) {
DEBUG(1, ("fill_grent_mem(): group rid %d not a local group\n",
group_rid));
@@ -174,8 +152,8 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
/* Lookup name */
- if (winbindd_lookup_by_name(server_name, &domain_sid, names[i],
- NULL, &name_type) == WINBINDD_OK) {
+ if (winbindd_lookup_sid_by_name(domain, names[i], NULL,
+ &name_type) == WINBINDD_OK) {
/* Check name type */
@@ -201,9 +179,9 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
/* Add group to todo list */
- if ((winbindd_lookup_by_name(server_name, &domain_sid,
- names[i], &todo_sid,
- &name_type) == WINBINDD_OK) &&
+ if ((winbindd_lookup_sid_by_name(domain, names[i],
+ &todo_sid, &name_type)
+ == WINBINDD_OK) &&
(todo_domain = strtok(names[i], "/\\"))) {
/* Fill in group entry */
@@ -298,9 +276,11 @@ static BOOL winbindd_fill_grent_mem(char *server_name, char *domain_name,
enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
{
- DOM_SID domain_sid, domain_group_sid;
- uint32 name_type, group_rid;
- fstring name_domain, name_group, temp_name, domain_controller;
+ DOM_SID domain_group_sid;
+ struct winbindd_domain *domain;
+ enum SID_NAME_USE name_type;
+ uint32 group_rid;
+ fstring name_domain, name_group, temp_name;
POSIX_ID surs_gid;
/* Look for group domain name */
@@ -311,8 +291,7 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
/* Get domain sid for the domain */
- if (!find_domain_sid_from_name(name_domain, &domain_sid,
- domain_controller)) {
+ if ((domain = find_domain_sid_from_name(name_domain)) == NULL) {
DEBUG(0, ("getgrname_from_group(): could not get domain sid for "
"domain %s\n", name_domain));
return WINBINDD_ERROR;
@@ -320,20 +299,13 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
/* Get rid and name type from NT server */
- if ((strcmp(name_domain, "BUILTIN") == 0) &&
- !winbindd_lookup_by_name(domain_controller, global_sid_builtin,
- name_group, &domain_group_sid,
+ if (!winbindd_lookup_sid_by_name(domain, name_group, &domain_group_sid,
&name_type)) {
- DEBUG(1, ("builtin group name %s does not exist\n", name_group));
+ DEBUG(1, ("group %s in domain %s does not exist\n", name_group,
+ name_domain));
return WINBINDD_ERROR;
}
- if (!winbindd_lookup_by_name(domain_controller, &domain_sid, name_group,
- &domain_group_sid, &name_type)) {
- DEBUG(1, ("group name %s does not exist\n", name_group));
- return WINBINDD_ERROR;
- }
-
if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
DEBUG(1, ("from_group: name '%s' is not a local or domain group: %d\n",
name_group, name_type));
@@ -342,8 +314,8 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
/* Fill in group structure */
- if (!winbindd_surs_sam_sid_to_unixid(&domain_group_sid, name_type,
- &surs_gid)) {
+ if (!winbindd_surs_sam_sid_to_unixid(domain, &domain_group_sid,
+ name_type, &surs_gid)) {
DEBUG(1, ("error sursing unix gid for sid\n"));
return WINBINDD_ERROR;
@@ -354,8 +326,7 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
sid_split_rid(&domain_group_sid, &group_rid);
- if (!winbindd_fill_grent_mem(domain_controller, name_domain,
- group_rid, name_type, NULL,
+ if (!winbindd_fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr)) {
return WINBINDD_ERROR;
}
@@ -367,48 +338,48 @@ enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_state *state)
enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_state *state)
{
- DOM_SID domain_sid, domain_group_sid;
- uint32 name_type, group_rid;
- fstring group_name, domain_controller, domain_name;
+ struct winbindd_domain *domain;
+ DOM_SID domain_group_sid;
+ enum SID_NAME_USE name_type;
+ uint32 group_rid;
+ fstring group_name;
POSIX_ID surs_gid;
+ /* Find domain controller and domain sid */
+
+ if ((domain = find_domain_from_gid(state->request.data.gid)) == NULL) {
+ DEBUG(0, ("Could not find domain for gid %d\n",
+ state->request.data.gid));
+ return WINBINDD_ERROR;
+ }
+
/* Get sid from gid */
surs_gid.type = SURS_POSIX_GID_AS_GRP;
surs_gid.id = state->request.data.gid;
- if (!winbindd_surs_unixid_to_sam_sid(&surs_gid, &domain_group_sid,
- False)) {
+ if (!winbindd_surs_unixid_to_sam_sid(domain, &surs_gid,
+ &domain_group_sid)) {
surs_gid.type = SURS_POSIX_GID_AS_ALS;
- if (!winbindd_surs_unixid_to_sam_sid(&surs_gid, &domain_group_sid,
- False)) {
+ if (!winbindd_surs_unixid_to_sam_sid(domain, &surs_gid,
+ &domain_group_sid)) {
DEBUG(1, ("Could not convert gid %d to domain or local sid\n",
state->request.data.gid));
return WINBINDD_ERROR;
}
}
- /* Find domain controller and domain sid */
-
- if (!find_domain_sid_from_gid(state->request.data.gid, &domain_sid,
- domain_controller, domain_name)) {
- DEBUG(0, ("Could not find domain for gid %d\n",
- state->request.data.gid));
- return WINBINDD_ERROR;
- }
-
/* Get name and name type from sid */
- if (!winbindd_lookup_by_sid(domain_controller, &domain_sid,
- &domain_group_sid, group_name, &name_type)) {
+ if (!winbindd_lookup_name_by_sid(domain, &domain_group_sid, group_name,
+ &name_type)) {
DEBUG(1, ("Could not lookup sid\n"));
return WINBINDD_ERROR;
}
- if (!((name_type == SID_NAME_ALIAS) ||
- (name_type == SID_NAME_DOM_GRP))) {
+ if (!((name_type == SID_NAME_ALIAS) || (name_type == SID_NAME_DOM_GRP))) {
DEBUG(1, ("from_gid: name '%s' is not a local or domain group: %d\n",
group_name, name_type));
return WINBINDD_ERROR;
@@ -420,8 +391,7 @@ enum winbindd_result winbindd_getgrnam_from_gid(struct winbindd_state *state)
sid_split_rid(&domain_group_sid, &group_rid);
- if (!winbindd_fill_grent_mem(domain_controller, domain_name,
- group_rid, name_type, NULL,
+ if (!winbindd_fill_grent_mem(domain, group_rid, name_type,
&state->response.data.gr)) {
return WINBINDD_ERROR;
}
@@ -452,7 +422,6 @@ enum winbindd_result winbindd_setgrent(struct winbindd_state *state)
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
struct getent_state *domain_state;
- BOOL res;
/* Create a state record for this domain */
@@ -464,40 +433,10 @@ enum winbindd_result winbindd_setgrent(struct winbindd_state *state)
ZERO_STRUCTP(domain_state);
- /* Connect to sam database */
-
- res = samr_connect(tmp->domain_controller, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &domain_state->sam_handle);
-
- {
- fstring sid_str;
-
- sid_to_string(sid_str, &tmp->domain_sid);
- fprintf(stderr, "opening pipe to %s, domain %s\n",
- sid_str, tmp->domain_name);
- }
-
- res = res ? samr_open_domain(&domain_state->sam_handle,
- 0x304, &tmp->domain_sid,
- &domain_state->sam_dom_handle) : False;
-
- if (res) {
-
- /* Add to list of open domains */
-
- fstrcpy(domain_state->domain_name, tmp->domain_name);
+ /* Add to list of open domains */
- DLIST_ADD(state->getgrent_state, domain_state);
-
- } else {
-
- /* Error opening sam pipes */
-
- samr_close(&domain_state->sam_dom_handle);
- samr_close(&domain_state->sam_handle);
-
- free(domain_state);
- }
+ domain_state->domain = tmp;
+ DLIST_ADD(state->getgrent_state, domain_state);
}
return WINBINDD_OK;
@@ -533,13 +472,15 @@ enum winbindd_result winbindd_getgrent(struct winbindd_state *state)
/* Get list of groups for this domain */
- if (strcmp(ent->domain_name, "BUILTIN") == 0) {
+ if (!open_sam_handles(ent->domain)) goto cleanup;
+
+ if (strcmp(ent->domain->name, "BUILTIN") == 0) {
/* Enumerate aliases */
do {
status =
- samr_enum_dom_aliases(&ent->sam_dom_handle,
+ samr_enum_dom_aliases(&ent->domain->sam_dom_handle,
&start_ndx, 0x100000,
&ent->sam_entries,
&ent->num_sam_entries);
@@ -551,7 +492,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_state *state)
do {
status =
- samr_enum_dom_groups(&ent->sam_dom_handle,
+ samr_enum_dom_groups(&ent->domain->sam_dom_handle,
&start_ndx, 0x100000,
&ent->sam_entries,
&ent->num_sam_entries);
@@ -561,20 +502,13 @@ enum winbindd_result winbindd_getgrent(struct winbindd_state *state)
do {
status =
- samr_enum_dom_aliases(&ent->sam_dom_handle,
+ samr_enum_dom_aliases(&ent->domain->sam_dom_handle,
&start_ndx2, 0x100000,
&ent->sam_entries,
&ent->num_sam_entries);
} while (status == STATUS_MORE_ENTRIES);
}
- fprintf(stderr, "*** read %d sam entries\n", ent->num_sam_entries);
-
- /* Close down pipes */
-
- samr_close(&ent->sam_dom_handle);
- samr_close(&ent->sam_handle);
-
ent->got_sam_entries = True;
}
@@ -588,7 +522,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_state *state)
/* Prepend domain to name */
- fstrcpy(domain_group_name, ent->domain_name);
+ fstrcpy(domain_group_name, ent->domain->name);
fstrcat(domain_group_name, "/");
fstrcat(domain_group_name, group_name);
@@ -612,6 +546,8 @@ enum winbindd_result winbindd_getgrent(struct winbindd_state *state)
/* We've exhausted all users for this pipe - close it down and
start on the next one. */
+ cleanup:
+
if (ent->sam_entries != NULL) free(ent->sam_entries);
ent->sam_entries = NULL;
diff --git a/source/nsswitch/winbindd_surs.c b/source/nsswitch/winbindd_surs.c
index d9a0ec3079e..0061f9f8e93 100644
--- a/source/nsswitch/winbindd_surs.c
+++ b/source/nsswitch/winbindd_surs.c
@@ -23,164 +23,10 @@
#include "sids.h"
#include "lib/surs.h"
-/* Initialise winbindd_surs database */
-
-BOOL winbindd_surs_init(void)
-{
- fstring value;
- char *p;
-
- /* Parse list of domains and uid ranges from "winbind uid" parameter */
-
- fstrcpy(value, lp_winbind_uid());
-
- for (p = strtok(value, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
- struct winbindd_domain_uid *uid;
- struct winbindd_domain *domain;
- fstring domain_name;
-
- /* Create new domain uid entry */
-
- if ((uid = (struct winbindd_domain_uid *)
- malloc(sizeof(*uid))) == NULL) {
-
- return False;
- }
-
- ZERO_STRUCTP(uid);
-
- /* Store info */
-
- if ((sscanf(p, "%[^/]/%u-%u", domain_name, &uid->uid_low,
- &uid->uid_high) != 3) &&
- (sscanf(p, "%[^/]/%u", domain_name, &uid->uid_low) != 2)) {
-
- DEBUG(0, ("surs_init(): winbid uid parameter invalid\n"));
- free(uid);
- return False;
- }
-
- if (uid->uid_high == 0) {
- uid->uid_high = -1;
- }
-
- if ((domain = find_domain_from_name(domain_name)) == NULL) {
- fstring sid_str;
-
- /* Create new domain entry */
-
- if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain)))
- == NULL) {
- return False;
- }
-
- fstrcpy(domain->domain_name, domain_name);
-
- /* Lookup domain sid */
-
- if (strequal(domain_name, "BUILTIN")) {
- sid_copy(&domain->domain_sid, global_sid_builtin);
- lookup_domain_sid(lp_workgroup(), NULL,
- domain->domain_controller);
- } else if (!lookup_domain_sid(domain->domain_name,
- &domain->domain_sid,
- domain->domain_controller)) {
- DEBUG(0, ("surs_init(): could not find domain sid for "
- "domain %s\n", domain->domain_name));
- return False;
- }
-
- sid_to_string(sid_str, &domain->domain_sid);
- DEBUG(0, ("Found sid %s for domain %s, controller %s\n",
- sid_str, domain->domain_name,
- domain->domain_controller));
-
- DLIST_ADD(domain_list, domain);
- }
-
- uid->domain = domain;
-
- /* Add to list */
-
- DLIST_ADD(domain_uid_list, uid);
- }
-
- /* Parse list of domains and gid ranges from "winbind gid" parameter */
-
- fstrcpy(value, lp_winbind_gid());
-
- for (p = strtok(value, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
- struct winbindd_domain_gid *gid;
- struct winbindd_domain *domain;
- fstring domain_name;
-
- /* Create new domain entry */
-
- if ((gid = (struct winbindd_domain_gid *)
- malloc(sizeof(*gid))) == NULL) {
-
- return False;
- }
-
- ZERO_STRUCTP(gid);
-
- /* Store info */
-
- if ((sscanf(p, "%[^/]/%u-%u", domain_name, &gid->gid_low,
- &gid->gid_high) != 3) &&
- (sscanf(p, "%[^/]/%u", domain_name, &gid->gid_low) != 2)) {
- DEBUG(0, ("surs_init(): winbid gid parameter invalid\n"));
- free(gid);
- return False;
- }
-
- if (gid->gid_high == 0) {
- gid->gid_high = -1;
- }
-
- /* Lookup domain sid */
-
- if ((domain = find_domain_from_name(domain_name)) == NULL) {
-
- /* Create new domain entry */
-
- if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain)))
- == NULL) {
- return False;
- }
-
- fstrcpy(domain->domain_name, domain_name);
-
- /* Lookup domain sid */
-
- if (strequal(domain_name, "BUILTIN")) {
- sid_copy(&domain->domain_sid, global_sid_builtin);
- lookup_domain_sid(lp_workgroup(), NULL,
- domain->domain_controller);
- } else if (!lookup_domain_sid(domain->domain_name,
- &domain->domain_sid,
- domain->domain_controller)) {
- DEBUG(0, ("surs_init(): could not find domain sid for "
- "domain %s\n", domain->domain_name));
- return False;
- }
-
- DLIST_ADD(domain_list, domain);
- }
-
- gid->domain = domain;
-
- /* Add to list */
-
- DLIST_ADD(domain_gid_list, gid);
- }
-
- return True;
-}
-
/* Wrapper around "standard" surs sid to unixid function */
-BOOL winbindd_surs_sam_sid_to_unixid(DOM_SID *sid,
+BOOL winbindd_surs_sam_sid_to_unixid(struct winbindd_domain *domain,
+ DOM_SID *sid,
enum SID_NAME_USE name_type,
POSIX_ID *id)
{
@@ -193,47 +39,37 @@ BOOL winbindd_surs_sam_sid_to_unixid(DOM_SID *sid,
sid_to_string(temp, &tmp_sid);
- /* User names */
-
- if (name_type == SID_NAME_USER) {
- struct winbindd_domain_uid *uid;
-
- for(uid = domain_uid_list; uid != NULL; uid = uid->next) {
+ if (sid_equal(&domain->sid, &tmp_sid)) {
- if (sid_equal(&uid->domain->domain_sid, &tmp_sid)) {
+ /* Check users */
- if ((uid->uid_low + rid) > uid->uid_high) {
- DEBUG(0, ("uid range to small for rid %d\n", rid));
- return False;
- }
+ if (name_type == SID_NAME_USER) {
- id->id = uid->uid_low + rid;
- id->type = SURS_POSIX_UID_AS_USR;
-
- return True;
+ if ((domain->uid_low + rid) > domain->uid_high) {
+ DEBUG(0, ("uid range to small for rid %d\n", rid));
+ return False;
}
+
+ id->id = domain->uid_low + rid;
+ id->type = SURS_POSIX_UID_AS_USR;
+
+ return True;
}
- }
-
- /* Domain groups */
-
- if ((name_type == SID_NAME_DOM_GRP) || (name_type == SID_NAME_ALIAS)) {
- struct winbindd_domain_gid *gid;
- for(gid = domain_gid_list; gid != NULL; gid = gid->next) {
-
- if (sid_equal(&gid->domain->domain_sid, &tmp_sid)) {
-
- if ((gid->gid_low + rid) > gid->gid_high) {
- DEBUG(0, ("gid range too small for rid %d\n", rid));
- return False;
- }
-
- id->id = gid->gid_low + rid;
- id->type = SURS_POSIX_GID_AS_GRP;
-
- return True;
+ /* Check domain and local groups */
+
+ if ((name_type == SID_NAME_DOM_GRP) ||
+ (name_type == SID_NAME_ALIAS)) {
+
+ if ((domain->gid_low + rid) > domain->gid_high) {
+ DEBUG(0, ("gid range too small for rid %d\n", rid));
+ return False;
}
+
+ id->id = domain->gid_low + rid;
+ id->type = SURS_POSIX_GID_AS_GRP;
+
+ return True;
}
}
@@ -242,47 +78,41 @@ BOOL winbindd_surs_sam_sid_to_unixid(DOM_SID *sid,
/* Wrapper around "standard" surs unixd to sid function */
-BOOL winbindd_surs_unixid_to_sam_sid(POSIX_ID *id, DOM_SID *sid, BOOL create)
+BOOL winbindd_surs_unixid_to_sam_sid(struct winbindd_domain *domain,
+ POSIX_ID *id, DOM_SID *sid)
{
- /* Process user uid */
+ /* Process user id */
if (id->type == SURS_POSIX_UID_AS_USR) {
- struct winbindd_domain_uid *uid;
- for(uid = domain_uid_list; uid != NULL; uid = uid->next) {
- if ((id->id >= uid->uid_low) && (id->id <= uid->uid_high)) {
+ if ((id->id >= domain->uid_low) && (id->id <= domain->uid_high)) {
- /* uid falls within range for this domain */
-
- if (sid != NULL) {
- sid_copy(sid, &uid->domain->domain_sid);
- sid_append_rid(sid, id->id - uid->uid_low);
- }
-
- return True;
+ /* uid falls within range for this domain */
+
+ if (sid != NULL) {
+ sid_copy(sid, &domain->sid);
+ sid_append_rid(sid, id->id - domain->uid_low);
}
+
+ return True;
}
}
-
- /* Process group gid */
-
- if ((id->type == SURS_POSIX_GID_AS_GRP) ||
+
+ /* Process group id */
+
+ if ((id->type == SURS_POSIX_GID_AS_GRP) ||
(id->type == SURS_POSIX_GID_AS_ALS)) {
- struct winbindd_domain_gid *gid;
-
- for(gid = domain_gid_list; gid != NULL; gid = gid->next) {
- if ((id->id >= gid->gid_low) && (id->id <= gid->gid_high)) {
-
- /* gid falls within range for this domain */
-
- if (sid != NULL) {
- sid_copy(sid, &gid->domain->domain_sid);
- sid_append_rid(sid, id->id - gid->gid_low);
- }
-
- return True;
+ if ((id->id >= domain->gid_low) && (id->id <= domain->gid_high)) {
+
+ /* gid falls within range for this domain */
+
+ if (sid != NULL) {
+ sid_copy(sid, &domain->sid);
+ sid_append_rid(sid, id->id - domain->gid_low);
}
+
+ return True;
}
}
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index cb2de8ea966..3bc548fab5a 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -22,81 +22,160 @@
*/
#include "includes.h"
+#include "sids.h"
-/* Connect to a domain controller and return the domain name and sid */
+/* Connect to a domain controller using get_any_dc_name() to discover
+ the domain name and sid */
-BOOL lookup_domain_sid(fstring domain_name, DOM_SID *domain_sid,
- fstring domain_controller)
+BOOL lookup_domain_sid(fstring domain_name, struct winbindd_domain *domain)
{
- POLICY_HND lsa_handle;
- DOM_SID level3_sid, level5_sid;
- fstring level3_dom, level5_dom;
- fstring system_name;
+ fstring level5_dom;
BOOL res;
- if (!get_any_dc_name(domain_name, system_name)) {
+ if (domain == NULL) {
return False;
}
- if (domain_controller != NULL) {
- fstrcpy(domain_controller, system_name);
+ if (!get_any_dc_name(domain_name, domain->controller)) {
+ return False;
}
- /* Get SID from domain controller */
+ /* Get SID from domain controller. We must call lsa_open_policy()
+ directly to avoid an infinite loop with open_lsa_handle() function. */
+
+ domain->lsa_handle_open =
+ lsa_open_policy(domain->controller, &domain->lsa_handle, False,
+ SEC_RIGHTS_MAXIMUM_ALLOWED);
+
+ res = domain->lsa_handle_open ?
+ lsa_query_info_pol(&domain->lsa_handle, 0x05, level5_dom,
+ &domain->sid) : False;
- res = lsa_open_policy(system_name, &lsa_handle, False,
- SEC_RIGHTS_MAXIMUM_ALLOWED);
+ return res;
+}
- res = res ? lsa_query_info_pol(&lsa_handle, 0x03, level3_dom,
- &level3_sid) : False;
+/* Lookup domain controller and sid for a domain */
- res = res ? lsa_query_info_pol(&lsa_handle, 0x05, level5_dom,
- &level5_sid) : False;
+BOOL get_domain_info(struct winbindd_domain *domain)
+{
+ fstring sid_str;
+
+ /* Lookup domain sid */
+
+ if (strequal(domain->name, "BUILTIN")) {
+ if (!lookup_domain_sid(lp_workgroup(), domain)) {
+ DEBUG(0, ("could not find sid for domain %s\n",
+ domain->name));
+ return False;
+ }
+
+ /* Fake up sid and domain controller */
+
+ sid_copy(&domain->sid, global_sid_builtin);
+ fstrcpy(domain->name, "BUILTIN");
+
+ } else if (!lookup_domain_sid(domain->name, domain)) {
+ DEBUG(0, ("could not find sid for domain %s\n", domain->name));
+ return False;
+ }
+
+ domain->got_domain_info = 1;
- lsa_close(&lsa_handle);
+ sid_to_string(sid_str, &domain->sid);
+ DEBUG(0, ("found sid %s for domain %s\n", sid_str, domain->name));
- /* Return domain sid if successful */
+ return True;
+}
- if (res && (domain_sid != NULL)) {
- sid_copy(domain_sid, &level5_sid);
- fstrcpy(domain_name, level5_dom);
+/* Open a lsa handle to a domain and cache the result */
+
+BOOL open_lsa_handle(struct winbindd_domain *domain)
+{
+ /* Get domain info */
+
+ if (!domain->got_domain_info) {
+ domain->got_domain_info = get_domain_info(domain);
}
- return res;
+ /* Open lsa handle if it isn't already open */
+
+ if (domain->got_domain_info && !domain->lsa_handle_open) {
+ domain->lsa_handle_open =
+ lsa_open_policy(domain->controller, &domain->lsa_handle, False,
+ SEC_RIGHTS_MAXIMUM_ALLOWED);
+ }
+
+ return domain->lsa_handle_open;
}
-/* Lookup a sid and type within a domain from a username */
+/* Open sam and sam domain handles to a domain and cache the results */
-BOOL winbindd_lookup_by_name(char *system_name, DOM_SID *level5_sid,
- fstring name, DOM_SID *sid,
- enum SID_NAME_USE *type)
+BOOL open_sam_handles(struct winbindd_domain *domain)
+{
+ /* Get domain info */
+
+ if (!domain->got_domain_info) {
+ domain->got_domain_info = get_domain_info(domain);
+ }
+
+ /* Open sam handle if it isn't already open */
+
+ if (domain->got_domain_info && !domain->sam_handle_open) {
+ domain->sam_handle_open =
+ samr_connect(domain->controller, SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sam_handle);
+ }
+
+ /* Open sam domain handle if it isn't already open */
+
+ if (domain->sam_handle_open && !domain->sam_dom_handle_open) {
+ domain->sam_dom_handle_open =
+ samr_open_domain(&domain->sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
+ &domain->sid, &domain->sam_dom_handle);
+ }
+
+ return domain->sam_dom_handle_open;
+}
+
+/* Lookup a sid in a domain from a name */
+
+BOOL winbindd_lookup_sid_by_name(struct winbindd_domain *domain,
+ fstring name, DOM_SID *sid,
+ enum SID_NAME_USE *type)
{
- POLICY_HND lsa_handle;
- BOOL res;
- DOM_SID *sids = NULL;
int num_sids = 0, num_names = 1;
+ DOM_SID *sids = NULL;
uint32 *types = NULL;
+ BOOL res;
+
+ /* Don't bother with machine accounts */
- if (name == NULL) {
- return 0;
+ if (name[strlen(name) - 1] == '$') {
+ return False;
}
- res = lsa_open_policy(system_name, &lsa_handle, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED);
-
- res = res ? lsa_lookup_names(&lsa_handle, num_names, (char **)&name,
- &sids, &types, &num_sids) : False;
+ /* Open handles */
- lsa_close(&lsa_handle);
+ if (!open_lsa_handle(domain)) return False;
+
+ /* Lookup name */
+
+ res = domain->lsa_handle_open ?
+ lsa_lookup_names(&domain->lsa_handle, num_names, (char **)&name,
+ &sids, &types, &num_sids) : False;
/* Return rid and type if lookup successful */
if (res) {
+ /* Return sid */
+
if ((sid != NULL) && (sids != NULL)) {
sid_copy(sid, &sids[0]);
}
+ /* Return name type */
+
if ((type != NULL) && (types != NULL)) {
*type = types[0];
}
@@ -104,39 +183,45 @@ BOOL winbindd_lookup_by_name(char *system_name, DOM_SID *level5_sid,
/* Free memory */
- if (types != NULL) { free(types); }
- if (sids != NULL) { free(sids); }
+ if (types != NULL) free(types);
+ if (sids != NULL) free(sids);
return res;
}
-/* Lookup a name and type within a domain from a sid */
+/* Lookup a name in a domain from a sid */
-int winbindd_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
- DOM_SID *sid, char *name,
- enum SID_NAME_USE *type)
+BOOL winbindd_lookup_name_by_sid(struct winbindd_domain *domain,
+ DOM_SID *sid, char *name,
+ enum SID_NAME_USE *type)
{
- POLICY_HND lsa_handle;
int num_sids = 1, num_names = 0;
uint32 *types = NULL;
char **names;
BOOL res;
- res = lsa_open_policy(system_name, &lsa_handle, True,
- SEC_RIGHTS_MAXIMUM_ALLOWED);
+ /* Open handles */
+
+ if (!open_lsa_handle(domain)) return False;
- res = res ? lsa_lookup_sids(&lsa_handle, num_sids, &sid,
- &names, &types, &num_names) : False;
+ /* Lookup name */
- lsa_close(&lsa_handle);
+ res = domain->lsa_handle_open ?
+ lsa_lookup_sids(&domain->lsa_handle, num_sids, &sid, &names,
+ &types, &num_names) : False;
/* Return name and type if successful */
if (res) {
+
+ /* Return name */
+
if ((names != NULL) && (name != NULL)) {
fstrcpy(name, names[0]);
}
+ /* Return name type */
+
if ((type != NULL) && (types != NULL)) {
*type = types[0];
}
@@ -144,7 +229,7 @@ int winbindd_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
/* Free memory */
- if (types != NULL) { free(types); }
+ if (types != NULL) free(types);
if (names != NULL) {
int i;
@@ -153,8 +238,8 @@ int winbindd_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
if (names[i] != NULL) {
free(names[i]);
}
- free(names);
}
+ free(names);
}
return res;
@@ -162,177 +247,105 @@ int winbindd_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
/* Lookup user information from a rid */
-int winbindd_lookup_userinfo(char *system_name, DOM_SID *dom_sid,
- uint32 user_rid, POLICY_HND *sam_dom_handle,
- SAM_USERINFO_CTR *user_info)
+BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
+ uint32 user_rid, SAM_USERINFO_CTR *user_info)
{
- POLICY_HND sam_handle, local_sam_dom_handle;
- BOOL res = True, local_handle = False;
-
- if (sam_dom_handle == NULL) {
- sam_dom_handle = &local_sam_dom_handle;
- local_handle = True;
- }
-
- /* Open connection to SAM pipe and SAM domain */
-
- if (local_handle) {
+ BOOL res;
- res = samr_connect(system_name, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &sam_handle);
+ /* Open handles */
- res = res ? samr_open_domain(&sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
- dom_sid, sam_dom_handle) : False;
- }
+ if (!open_sam_handles(domain)) return False;
/* Get user info */
- res = res ? get_samr_query_userinfo(sam_dom_handle, 0x15,
- user_rid, user_info) : False;
-
- /* Close up shop */
-
- if (local_handle) {
- samr_close(sam_dom_handle);
- samr_close(&sam_handle);
- }
+ res = domain->sam_dom_handle_open ?
+ get_samr_query_userinfo(&domain->sam_dom_handle, 0x15, user_rid,
+ user_info) : False;
return res;
}
/* Lookup group information from a rid */
-int winbindd_lookup_groupinfo(char *system_name, DOM_SID *dom_sid,
+BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
uint32 group_rid, GROUP_INFO_CTR *info)
{
- POLICY_HND sam_handle, sam_dom_handle;
BOOL res;
- /* Open connection to SAM pipe and SAM domain */
+ /* Open pipes */
- res = samr_connect(system_name, SEC_RIGHTS_MAXIMUM_ALLOWED, &sam_handle);
+ if (!open_sam_handles(domain)) return False;
- res = res ? samr_open_domain(&sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
- dom_sid, &sam_dom_handle) : False;
/* Query group info */
- res = res ? get_samr_query_groupinfo(&sam_dom_handle, 1,
- group_rid, info) : False;
-
- /* Close up shop */
-
- samr_close(&sam_dom_handle);
- samr_close(&sam_handle);
+ res = domain->sam_dom_handle_open ?
+ get_samr_query_groupinfo(&domain->sam_dom_handle, 1, group_rid,
+ info) : False;
return res;
}
/* Lookup group membership given a rid */
-int winbindd_lookup_groupmem(char *system_name, DOM_SID *dom_sid,
- uint32 group_rid, POLICY_HND *sam_dom_handle,
- uint32 *num_names, uint32 **rid_mem,
- char ***names, uint32 **name_types)
+BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
+ uint32 group_rid, uint32 *num_names,
+ uint32 **rid_mem, char ***names,
+ enum SID_NAME_USE **name_types)
{
- POLICY_HND sam_handle, local_sam_dom_handle;
- BOOL res = True, local_handle = False;
-
- if (sam_dom_handle == NULL) {
- sam_dom_handle = &local_sam_dom_handle;
- local_handle = True;
- }
-
- /* Open connection to SAM pipe and SAM domain */
+ BOOL res;
- if (local_handle) {
+ /* Open pipes */
- res = samr_connect(system_name, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &sam_handle);
+ if (!open_sam_handles(domain)) return False;
- res = res ? samr_open_domain(&sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
- dom_sid, sam_dom_handle) : False;
- }
/* Query group membership */
- res = res ? sam_query_groupmem(sam_dom_handle, group_rid, num_names,
- rid_mem, names, name_types) : False;
-
- /* Close up shop */
-
- if (local_handle) {
- samr_close(sam_dom_handle);
- samr_close(&sam_handle);
- }
+ res = domain->sam_dom_handle_open ?
+ sam_query_groupmem(&domain->sam_dom_handle, group_rid, num_names,
+ rid_mem, names, name_types) : False;
return res;
}
/* Lookup alias membership given a rid */
-int winbindd_lookup_aliasmem(char *system_name, DOM_SID *dom_sid,
- uint32 alias_rid, POLICY_HND *sam_dom_handle,
- uint32 *num_names, DOM_SID ***sids,
- char ***names, uint32 **name_types)
+int winbindd_lookup_aliasmem(struct winbindd_domain *domain,
+ uint32 alias_rid, uint32 *num_names,
+ DOM_SID ***sids, char ***names,
+ enum SID_NAME_USE **name_types)
{
- POLICY_HND sam_handle, local_sam_dom_handle;
- BOOL res = True, local_handle = False;
-
- if (sam_dom_handle == NULL) {
- sam_dom_handle = &local_sam_dom_handle;
- local_handle = True;
- }
-
- /* Open connection to SAM pipe and SAM domain */
+ BOOL res;
- if (local_handle) {
+ /* Open sam handles */
- res = samr_connect(system_name, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &sam_handle);
-
- res = res ? samr_open_domain(&sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
- dom_sid, sam_dom_handle) : False;
- }
+ if (!open_sam_handles(domain)) return False;
/* Query alias membership */
- res = res ? sam_query_aliasmem(system_name, sam_dom_handle, alias_rid,
- num_names, sids, names, name_types)
- : False;
-
- /* Close up shop */
-
- if (local_handle) {
- samr_close(sam_dom_handle);
- samr_close(&sam_handle);
- }
+ res = domain->sam_dom_handle_open ?
+ sam_query_aliasmem(domain->controller, &domain->sam_dom_handle,
+ alias_rid, num_names, sids, names,
+ name_types) : False;
return res;
}
/* Lookup alias information given a rid */
-int winbindd_lookup_aliasinfo(char *system_name, DOM_SID *dom_sid,
+int winbindd_lookup_aliasinfo(struct winbindd_domain *domain,
uint32 alias_rid, ALIAS_INFO_CTR *info)
{
- POLICY_HND sam_handle, sam_dom_handle;
BOOL res;
- /* Open connection to SAM pipe and SAM domain */
+ /* Open pipes */
- res = samr_connect(system_name, SEC_RIGHTS_MAXIMUM_ALLOWED,
- &sam_handle);
+ if (!open_sam_handles(domain)) return False;
- res = res ? samr_open_domain(&sam_handle, SEC_RIGHTS_MAXIMUM_ALLOWED,
- dom_sid, &sam_dom_handle) : False;
/* Query group info */
- res = res ? get_samr_query_aliasinfo(&sam_dom_handle, 1,
- alias_rid, info) : False;
-
- /* Close up shop */
-
- samr_close(&sam_dom_handle);
- samr_close(&sam_handle);
+ res = domain->sam_dom_handle_open ?
+ get_samr_query_aliasinfo(&domain->sam_dom_handle, 1, alias_rid,
+ info) : False;
return res;
}
@@ -352,7 +365,14 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)
/* Search through list */
for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (strcmp(domain_name, tmp->domain_name) == 0) {
+ if (strcmp(domain_name, tmp->name) == 0) {
+
+ /* Get domain info for this domain */
+
+ if (!tmp->got_domain_info && !get_domain_info(tmp)) {
+ return NULL;
+ }
+
return tmp;
}
}
@@ -365,113 +385,72 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)
/* Given a domain name, return the domain sid and domain controller we
found in winbindd_surs_init(). */
-BOOL find_domain_sid_from_name(char *domain_name, DOM_SID *domain_sid,
- char *domain_controller)
+struct winbindd_domain *find_domain_sid_from_name(char *domain_name)
{
struct winbindd_domain *tmp;
/* Search through list */
for(tmp = domain_list; tmp != NULL; tmp = tmp->next) {
- if (strcmp(domain_name, tmp->domain_name) == 0) {
+ if (strcmp(domain_name, tmp->name) == 0) {
- /* Copy domain sid */
+ /* Get domain info for this domain */
- if (domain_sid != NULL) {
- sid_copy(domain_sid, &tmp->domain_sid);
+ if (!tmp->got_domain_info && !get_domain_info(tmp)) {
+ return NULL;
}
-
- /* Copy domain controller */
- if (domain_controller != NULL) {
- fstrcpy(domain_controller, tmp->domain_controller);
- }
-
- return True;
+ return tmp;
}
}
/* Not found */
- return False;
+ return NULL;
}
-/* Given a uid, return the domain sid and domain controller */
+/* Given a uid return the domain for which the uid falls in the uid range. */
-BOOL find_domain_sid_from_uid(uid_t uid, DOM_SID *domain_sid,
- char *domain_name,
- char *domain_controller)
+struct winbindd_domain *find_domain_from_uid(uid_t uid)
{
- struct winbindd_domain_uid *tmp;
-
- for(tmp = domain_uid_list; tmp != NULL; tmp = tmp->next) {
- if ((uid >= tmp->uid_low) && (uid <= tmp->uid_high) &&
- (tmp->domain != NULL)) {
-
- /* Copy domain sid */
-
- if (domain_sid != NULL) {
- sid_copy(domain_sid, &tmp->domain->domain_sid);
- }
-
- /* Copy domain controller */
+ struct winbindd_domain *tmp;
- if (domain_controller != NULL) {
- fstrcpy(domain_controller, tmp->domain->domain_controller);
- }
+ for(tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if ((uid >= tmp->uid_low) && (uid <= tmp->uid_high)) {
- /* Copy domain name */
+ /* Get domain info for this domain */
- if (domain_name != NULL) {
- fstrcpy(domain_name, tmp->domain->domain_name);
+ if (!tmp->got_domain_info && !get_domain_info(tmp)) {
+ return NULL;
}
- return True;
+ return tmp;
}
}
- /* Not found */
-
- return False;
+ return NULL;
}
-/* Given a uid, return the domain sid and domain controller */
+/* Given a gid return the domain for which the gid falls in the gid range. */
-BOOL find_domain_sid_from_gid(gid_t gid, DOM_SID *domain_sid,
- char *domain_controller,
- char *domain_name)
+struct winbindd_domain *find_domain_from_gid(gid_t gid)
{
- struct winbindd_domain_gid *tmp;
-
- for(tmp = domain_gid_list; tmp != NULL; tmp = tmp->next) {
- if ((gid >= tmp->gid_low) && (gid <= tmp->gid_high) &&
- (tmp->domain != NULL)) {
-
- /* Copy domain sid */
-
- if (domain_sid != NULL) {
- sid_copy(domain_sid, &tmp->domain->domain_sid);
- }
-
- /* Copy domain controller */
+ struct winbindd_domain *tmp;
- if (domain_controller != NULL) {
- fstrcpy(domain_controller, tmp->domain->domain_controller);
- }
+ for(tmp = domain_list; tmp != NULL; tmp = tmp->next) {
+ if ((gid >= tmp->gid_low) && (gid <= tmp->gid_high)) {
- /* Copy domain name */
+ /* Get domain info for this domain */
- if (domain_name != NULL) {
- fstrcpy(domain_name, tmp->domain->domain_name);
+ if (!tmp->got_domain_info && !get_domain_info(tmp)) {
+ return NULL;
}
- return True;
+ return tmp;
}
}
- /* Not found */
-
- return False;
+ return NULL;
}
/* Free state information held for {set,get,end}{pw,gr}ent() functions */
@@ -483,13 +462,6 @@ void free_getent_state(struct getent_state *state)
while(state != NULL) {
struct getent_state *next = state->next;
- /* Close sam handles if they are open */
-
- if (!state->got_sam_entries) {
- samr_close(&state->sam_dom_handle);
- samr_close(&state->sam_handle);
- }
-
/* Free any sam entries */
if (state->sam_entries != NULL) free(state->sam_entries);
@@ -501,3 +473,83 @@ void free_getent_state(struct getent_state *state)
state = next;
}
}
+
+/* Parse list of arguments to winbind uid or winbind gid parameters */
+
+static BOOL parse_id_list(char *paramstr, BOOL is_user)
+{
+ uid_t id_low, id_high = 0;
+ struct winbindd_domain *domain;
+ fstring domain_name;
+ char *p;
+
+ for (p = strtok(paramstr, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
+
+ /* Parse domain entry */
+
+ if ((sscanf(p, "%[^/]/%u-%u", domain_name, &id_low,
+ &id_high) != 3) &&
+ (sscanf(p, "%[^/]/%u", domain_name, &id_low) != 2)) {
+
+ DEBUG(0, ("surs_init(): winbid %s parameter invalid\n",
+ is_user ? "uid" : "gid"));
+ return False;
+ }
+
+ /* Find domain record */
+
+ if ((domain = find_domain_from_name(domain_name)) == NULL) {
+
+ /* Create new domain record */
+
+ if ((domain = (struct winbindd_domain *)malloc(sizeof(*domain)))
+ == NULL) {
+ return False;
+ }
+
+ ZERO_STRUCTP(domain);
+ fstrcpy(domain->name, domain_name);
+
+ DLIST_ADD(domain_list, domain);
+ }
+
+ /* Store domain id info */
+
+ if (is_user) {
+
+ /* Store user info */
+
+ domain->uid_low = id_low;
+
+ if (id_high == 0) {
+ domain->uid_high = -1;
+ } else {
+ domain->uid_high = id_high;
+ }
+
+ } else {
+
+ /* Store group info */
+
+ domain->gid_low = id_low;
+
+ if (id_high == 0) {
+ domain->gid_high = -1;
+ } else {
+ domain->gid_high = id_high;
+ }
+ }
+ }
+
+ return True;
+}
+
+/* Initialise trusted domain info */
+
+BOOL winbindd_param_init(void)
+{
+ /* Parse winbind uid and winbind_gid parameters */
+
+ return (parse_id_list(lp_winbind_uid(), True) &&
+ parse_id_list(lp_winbind_gid(), False));
+}