summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2001-10-05 00:20:06 +0000
committerTim Potter <tpot@samba.org>2001-10-05 00:20:06 +0000
commit482a9ef278567a35d3bcad1c2048ee97d86bfb9c (patch)
treea4cf752314cb3605aaa9c204c873f8b221df03ff /source3/nsswitch
parent18190fc0513d6fa8824fa0b105aeb16dd428106b (diff)
downloadsamba-482a9ef278567a35d3bcad1c2048ee97d86bfb9c.tar.gz
samba-482a9ef278567a35d3bcad1c2048ee97d86bfb9c.tar.bz2
samba-482a9ef278567a35d3bcad1c2048ee97d86bfb9c.zip
This is the start of a bit of a rewrite of winbindd's connection handling.
I've wrapped up all the decisions about managing, making and closing connections into a connection manager in nsswitch/winbindd_cm.c. It's rather incomplete at the moment - only querying basic user info works at the moment (i.e finger -m DOMAIN/user) and everything else is broken. Jeremy, please take a look and I'll start moving across the rest of winbindd to this new system. (This used to be commit c369cf5af787ed9c642778d21f162716fbf0620e)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd.c220
-rw-r--r--source3/nsswitch/winbindd.h22
-rw-r--r--source3/nsswitch/winbindd_cache.c29
-rw-r--r--source3/nsswitch/winbindd_cm.c245
-rw-r--r--source3/nsswitch/winbindd_group.c19
-rw-r--r--source3/nsswitch/winbindd_pam.c20
-rw-r--r--source3/nsswitch/winbindd_proto.h23
-rw-r--r--source3/nsswitch/winbindd_user.c36
-rw-r--r--source3/nsswitch/winbindd_util.c354
9 files changed, 588 insertions, 380 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 13b8478257..9bf4935eff 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -130,91 +130,92 @@ static void sighup_handler(int signum)
static int create_sock(void)
{
- struct sockaddr_un sunaddr;
- struct stat st;
- int sock;
- mode_t old_umask;
- pstring path;
-
- /* Create the socket directory or reuse the existing one */
-
- if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
-
- if (errno == ENOENT) {
-
- /* Create directory */
-
- if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) {
- DEBUG(0, ("error creating socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, strerror(errno)));
- return -1;
- }
-
+ struct sockaddr_un sunaddr;
+ struct stat st;
+ int sock;
+ mode_t old_umask;
+ pstring path;
+
+ /* Create the socket directory or reuse the existing one */
+
+ if (lstat(WINBINDD_SOCKET_DIR, &st) == -1) {
+
+ if (errno == ENOENT) {
+
+ /* Create directory */
+
+ if (mkdir(WINBINDD_SOCKET_DIR, 0755) == -1) {
+ DEBUG(0, ("error creating socket directory "
+ "%s: %s\n", WINBINDD_SOCKET_DIR,
+ strerror(errno)));
+ return -1;
+ }
+
+ } else {
+
+ DEBUG(0, ("lstat failed on socket directory %s: %s\n",
+ WINBINDD_SOCKET_DIR, strerror(errno)));
+ return -1;
+ }
+
} else {
-
- DEBUG(0, ("lstat failed on socket directory %s: %s\n",
- WINBINDD_SOCKET_DIR, strerror(errno)));
- return -1;
+
+ /* Check ownership and permission on existing directory */
+
+ if (!S_ISDIR(st.st_mode)) {
+ DEBUG(0, ("socket directory %s isn't a directory\n",
+ WINBINDD_SOCKET_DIR));
+ return -1;
+ }
+
+ if ((st.st_uid != sec_initial_uid()) ||
+ ((st.st_mode & 0777) != 0755)) {
+ DEBUG(0, ("invalid permissions on socket directory "
+ "%s\n", WINBINDD_SOCKET_DIR));
+ return -1;
+ }
}
-
- } else {
-
- /* Check ownership and permission on existing directory */
- if (!S_ISDIR(st.st_mode)) {
- DEBUG(0, ("socket directory %s isn't a directory\n",
- WINBINDD_SOCKET_DIR));
- return -1;
+ /* Create the socket file */
+
+ old_umask = umask(0);
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (sock == -1) {
+ perror("socket");
+ return -1;
}
- if ((st.st_uid != sec_initial_uid()) ||
- ((st.st_mode & 0777) != 0755)) {
- DEBUG(0, ("invalid permissions on socket directory %s\n",
- WINBINDD_SOCKET_DIR));
- return -1;
+ snprintf(path, sizeof(path), "%s/%s",
+ WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
+
+ unlink(path);
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_UNIX;
+ safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
+
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
+ DEBUG(0, ("bind failed on winbind socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ return -1;
}
- }
-
- /* Create the socket file */
-
- old_umask = umask(0);
-
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
- if (sock == -1) {
- perror("socket");
- return -1;
- }
-
- snprintf(path, sizeof(path), "%s/%s",
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
-
- unlink(path);
- memset(&sunaddr, 0, sizeof(sunaddr));
- sunaddr.sun_family = AF_UNIX;
- safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
-
- if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
- DEBUG(0, ("bind failed on winbind socket %s: %s\n",
- path,
- strerror(errno)));
- close(sock);
- return -1;
- }
-
- if (listen(sock, 5) == -1) {
- DEBUG(0, ("listen failed on winbind socket %s: %s\n",
- path,
- strerror(errno)));
- close(sock);
- return -1;
- }
-
- umask(old_umask);
-
- /* Success! */
-
- return sock;
+
+ if (listen(sock, 5) == -1) {
+ DEBUG(0, ("listen failed on winbind socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ return -1;
+ }
+
+ umask(old_umask);
+
+ /* Success! */
+
+ return sock;
}
struct dispatch_table {
@@ -228,9 +229,13 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_GETPWNAM_FROM_USER, winbindd_getpwnam_from_user },
{ WINBINDD_GETPWNAM_FROM_UID, winbindd_getpwnam_from_uid },
+
+#if 0
+
{ WINBINDD_SETPWENT, winbindd_setpwent },
{ WINBINDD_ENDPWENT, winbindd_endpwent },
{ WINBINDD_GETPWENT, winbindd_getpwent },
+
{ WINBINDD_GETGROUPS, winbindd_getgroups },
/* Group functions */
@@ -269,6 +274,8 @@ static struct dispatch_table dispatch_table[] = {
{ WINBINDD_CHECK_MACHACC, winbindd_check_machine_acct },
+#endif
+
/* End of list */
{ WINBINDD_NUM_CMDS, NULL }
@@ -290,8 +297,6 @@ static void process_request(struct winbindd_cli_state *state)
/* Process command */
- if (!server_state.lsa_handle_open) return;
-
for (table = dispatch_table; table->fn; table++) {
if (state->request.cmd == table->cmd) {
state->response.result = table->fn(state);
@@ -301,9 +306,8 @@ static void process_request(struct winbindd_cli_state *state)
/* In case extra data pointer is NULL */
- if (!state->response.extra_data) {
+ if (!state->response.extra_data)
state->response.length = sizeof(struct winbindd_response);
- }
}
/* Process a new connection by adding it to the client connection list */
@@ -319,20 +323,16 @@ static void new_connection(int accept_sock)
len = sizeof(sunaddr);
if ((sock = accept(accept_sock, (struct sockaddr *)&sunaddr, &len))
- == -1) {
-
+ == -1)
return;
- }
DEBUG(6,("accepted socket %d\n", sock));
/* Create new connection structure */
- if ((state = (struct winbindd_cli_state *)
- malloc(sizeof(*state))) == NULL) {
-
+ if ((state = (struct winbindd_cli_state *)
+ malloc(sizeof(*state))) == NULL)
return;
- }
ZERO_STRUCTP(state);
state->sock = sock;
@@ -508,10 +508,6 @@ static void process_loop(int accept_sock)
lp_talloc_free();
- /* Do any connection establishment that is needed */
-
- establish_connections(False); /* Honour timeout */
-
/* Initialise fd lists for select() */
FD_ZERO(&r_fds);
@@ -544,15 +540,13 @@ static void process_loop(int accept_sock)
/* Add fd for reading */
- if (state->read_buf_len != sizeof(state->request)) {
+ if (state->read_buf_len != sizeof(state->request))
FD_SET(state->sock, &r_fds);
- }
/* Add fd for writing */
- if (state->write_buf_len) {
+ if (state->write_buf_len)
FD_SET(state->sock, &w_fds);
- }
state = state->next;
}
@@ -566,12 +560,6 @@ static void process_loop(int accept_sock)
do_flush_caches();
reload_services_file(True);
- /* Close and re-open all connections. This will also
- refresh the trusted domains list */
-
- winbindd_kill_all_connections();
- establish_connections(True); /* Force re-establish */
-
do_sighup = False;
}
@@ -598,9 +586,8 @@ static void process_loop(int accept_sock)
if (selret > 0) {
- if (FD_ISSET(accept_sock, &r_fds)) {
+ if (FD_ISSET(accept_sock, &r_fds))
new_connection(accept_sock);
- }
/* Process activity on client connections */
@@ -625,9 +612,8 @@ static void process_loop(int accept_sock)
/* Data available for writing */
- if (FD_ISSET(state->sock, &w_fds)) {
+ if (FD_ISSET(state->sock, &w_fds))
client_write(state);
- }
}
}
}
@@ -645,10 +631,13 @@ int main(int argc, char **argv)
BOOL interactive = False;
int opt, new_debuglevel = -1;
+ /* Initialise for running in non-root mode */
+
sec_init();
/* Set environment variable so we don't recursively call ourselves.
This may also be useful interactively. */
+
SETENV(WINBINDD_DONT_ENV, "1", 1);
/* Initialise samba/rpc client stuff */
@@ -689,9 +678,8 @@ int main(int argc, char **argv)
fstrcpy(global_myname, myhostname());
p = strchr(global_myname, '.');
- if (p) {
+ if (p)
*p = 0;
- }
}
TimeInit();
@@ -701,13 +689,11 @@ int main(int argc, char **argv)
exit(1);
}
- if (new_debuglevel != -1) {
+ if (new_debuglevel != -1)
DEBUGLEVEL = new_debuglevel;
- }
- if (!interactive) {
+ if (!interactive)
become_daemon();
- }
load_interfaces();
@@ -717,13 +703,11 @@ int main(int argc, char **argv)
/* Winbind daemon initialisation */
- if (!winbindd_param_init()) {
+ if (!winbindd_param_init())
return 1;
- }
- if (!winbindd_idmap_init()) {
+ if (!winbindd_idmap_init())
return 1;
- }
winbindd_cache_init();
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index fe25d5ba5e..17282cf131 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -68,17 +68,11 @@ struct getpwent_user {
/* Server state structure */
struct winbindd_state {
- /* Netbios name of PDC */
- fstring controller;
-
+
/* User and group id pool */
+
uid_t uid_low, uid_high; /* Range of uids to allocate */
gid_t gid_low, gid_high; /* Range of gids to allocate */
-
- /* Cached handle to lsa pipe */
- CLI_POLICY_HND lsa_handle;
- BOOL lsa_handle_open;
- BOOL pwdb_initialised;
};
extern struct winbindd_state server_state; /* Server information */
@@ -90,22 +84,24 @@ struct winbindd_domain {
/* Domain information */
fstring name; /* Domain name */
- fstring controller; /* NetBIOS name of DC */
DOM_SID sid; /* SID for this domain */
BOOL got_domain_info; /* Got controller and sid */
/* Cached handles to samr pipe */
- CLI_POLICY_HND sam_handle, sam_dom_handle;
- BOOL sam_handle_open, sam_dom_handle_open;
- time_t last_check;
-
struct winbindd_domain *prev, *next; /* Linked list info */
};
extern struct winbindd_domain *domain_list; /* List of domains we know */
+/* Used to glue a policy handle and cli_state together */
+
+typedef struct {
+ struct cli_state *cli;
+ POLICY_HND pol;
+} CLI_POLICY_HND;
+
#include "winbindd_proto.h"
#include "rpc_parse.h"
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 3fa50abfba..9c0ad5015c 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -47,6 +47,35 @@ void winbindd_cache_init(void)
}
}
+/* find the sequence number for a domain */
+
+static uint32 domain_sequence_number(char *domain_name)
+{
+ return DOM_SEQUENCE_NONE;
+
+#if 0
+ struct winbindd_domain *domain;
+ SAM_UNK_CTR ctr;
+
+ domain = find_domain_from_name(domain_name);
+ if (!domain) return DOM_SEQUENCE_NONE;
+
+ if (!wb_samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
+
+ /* If this fails, something bad has gone wrong */
+
+ DEBUG(2,("domain sequence query failed\n"));
+ return DOM_SEQUENCE_NONE;
+ }
+
+ DEBUG(4,("got domain sequence number for %s of %u\n",
+ domain_name, (unsigned)ctr.info.inf2.seq_num));
+
+ return ctr.info.inf2.seq_num;
+#endif
+
+}
+
/* get the domain sequence number, possibly re-fetching */
static uint32 cached_sequence_number(char *domain_name)
{
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
new file mode 100644
index 0000000000..ec1db826dd
--- /dev/null
+++ b/source3/nsswitch/winbindd_cm.c
@@ -0,0 +1,245 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0
+
+ Winbind daemon connection manager
+
+ Copyright (C) Tim Potter 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ We need to manage connections to domain controllers without having to
+ mess up the main winbindd code with other issues. The aim of the
+ connection manager is to:
+
+ - make connections to domain controllers and cache them
+ - re-establish connections when networks or servers go down
+ - centralise the policy on connection timeouts, domain controller
+ selection etc
+ - manage re-entrancy for when winbindd becomes able to handle
+ multiple outstanding rpc requests
+
+ We can also throw away the CLI_POLICY_HND stuff as all this information
+ will be stored within this module.
+
+ Why not have connection management as part of the rpc layer like tng?
+ Good question. This code may morph into libsmb/rpc_cache.c or something
+ like that but at the moment it's simply staying as part of winbind. I
+ think the TNG architecture of forcing every user of the rpc layer to use
+ the connection caching system is a bad idea. It should be an optional
+ method of using the routines.
+
+ The TNG design is quite good but I disagree with some aspects of the
+ implementation. -tpot
+
+ */
+
+/*
+ TODO:
+
+ - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
+ moved down into another function.
+
+ - There needs to be a utility function in libsmb/namequery.c that does
+ get_any_dc_name()
+
+ */
+
+#include "winbindd.h"
+
+/* We store lists of connections here */
+
+struct winbindd_cm_conn {
+ struct winbindd_cm_conn *prev, *next;
+ fstring domain;
+ fstring controller;
+ fstring pipe_name;
+ struct cli_state cli;
+ POLICY_HND pol;
+};
+
+/* Global list of connections. Initially a DLIST but can become a hash
+ table or whatever later. */
+
+struct winbindd_cm_conn *cm_conns = NULL;
+
+/* Get a domain controller name */
+
+BOOL cm_get_dc_name(char *domain, fstring srv_name)
+{
+ struct in_addr *ip_list, dc_ip;
+ extern pstring global_myname;
+ int count, i;
+
+ /* Lookup domain controller name */
+
+ if (!get_dc_list(False, domain, &ip_list, &count))
+ return False;
+
+ /* Firstly choose a PDC/BDC who has the same network address as any
+ of our interfaces. */
+
+ for (i = 0; i < count; i++) {
+ if(!is_local_net(ip_list[i]))
+ goto got_ip;
+ }
+
+ i = (sys_random() % count);
+
+ got_ip:
+ dc_ip = ip_list[i];
+ SAFE_FREE(ip_list);
+
+ if (!lookup_pdc_name(global_myname, domain, &dc_ip, srv_name))
+ return False;
+
+ return True;
+}
+
+/* Open a new smb pipe connection to a DC on a given domain */
+
+static BOOL cm_open_connection(char *domain, char *pipe_name,
+ struct winbindd_cm_conn *new_conn)
+{
+ struct nmb_name calling, called;
+ extern pstring global_myname;
+ fstring dest_host;
+ struct in_addr dest_ip;
+ BOOL result = False;
+ struct ntuser_creds creds;
+
+ ZERO_STRUCT(new_conn->cli);
+
+ fstrcpy(new_conn->domain, domain);
+ fstrcpy(new_conn->pipe_name, pipe_name);
+
+ /* Look for a domain controller for this domain */
+
+ if (!cm_get_dc_name(lp_workgroup(), new_conn->controller))
+ goto done;
+
+ /* Initialise SMB connection */
+
+ if (!cli_initialise(&new_conn->cli))
+ goto done;
+
+ if (!resolve_srv_name(new_conn->controller, dest_host, &dest_ip))
+ goto done;
+
+ make_nmb_name(&called, dns_to_netbios_name(new_conn->controller),
+ 0x20);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
+
+ ZERO_STRUCT(creds);
+ creds.pwd.null_pwd = 1;
+
+ cli_init_creds(&new_conn->cli, &creds);
+
+ if (!cli_establish_connection(&new_conn->cli, new_conn->controller,
+ &dest_ip, &calling, &called, "IPC$",
+ "IPC", False, True))
+ goto done;
+
+ if (!cli_nt_session_open (&new_conn->cli, pipe_name))
+ goto done;
+
+ result = True;
+
+ done:
+ if (!result)
+ cli_shutdown(&new_conn->cli);
+
+ return result;
+}
+
+/* Return a LSA policy handle on a domain */
+
+CLI_POLICY_HND *cm_get_lsa_handle(char *domain)
+{
+ struct winbindd_cm_conn *conn;
+ uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED;
+ NTSTATUS result;
+ static CLI_POLICY_HND hnd;
+
+ /* Look for existing connections */
+
+ for (conn = cm_conns; conn; conn = conn->next) {
+ if (strequal(conn->domain, domain) &&
+ strequal(conn->pipe_name, PIPE_LSARPC))
+ goto ok;
+ }
+
+ /* Create a new one */
+
+ if (!(conn = (struct winbindd_cm_conn *)
+ malloc(sizeof(struct winbindd_cm_conn))))
+ return NULL;
+
+ if (!cm_open_connection(domain, PIPE_LSARPC, conn)) {
+ DEBUG(3, ("Could not connect to a dc for domain %s\n",
+ domain));
+ return NULL;
+ }
+
+ result = cli_lsa_open_policy(&conn->cli, conn->cli.mem_ctx, False,
+ des_access, &conn->pol);
+
+ if (!NT_STATUS_IS_OK(result))
+ return NULL;
+
+ /* Add to list */
+
+ DLIST_ADD(cm_conns, conn);
+
+ ok:
+ hnd.pol = conn->pol;
+ hnd.cli = &conn->cli;
+
+ return &hnd;
+}
+
+/* Return a SAM policy handle on a domain */
+
+CLI_POLICY_HND *cm_get_sam_handle(char *domain)
+{
+ DEBUG(0, ("get_sam_handle(): not implemented\n"));
+ return NULL;
+}
+
+/* Return a SAM domain policy handle on a domain */
+
+CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain)
+{
+ DEBUG(0, ("get_sam_dom_handle(): not implemented\n"));
+ return NULL;
+}
+
+/* Return a SAM policy handle on a domain user */
+
+CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user)
+{
+ DEBUG(0, ("get_sam_user_handle(): not implemented\n"));
+ return NULL;
+}
+
+/* Return a SAM policy handle on a domain group */
+
+CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, char *group)
+{
+ DEBUG(0, ("get_sam_group_handle(): not implemented\n"));
+ return NULL;
+}
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index ab693eff63..40ad100fc5 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -23,6 +23,8 @@
#include "winbindd.h"
+#if 0
+
/* Fill a grent structure from various other information */
static BOOL fill_grent(struct winbindd_gr *gr, char *gr_name,
@@ -496,15 +498,18 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
do {
struct acct_info *sam_grp_entries = NULL;
+ CLI_POLICY_HND *hnd;
num_entries = 0;
- status = wb_samr_enum_dom_groups(&ent->domain->sam_dom_handle,
- &ent->grp_query_start_ndx,
- 0x8000, /* buffer size? */
- (struct acct_info **)
- &sam_grp_entries,
- &num_entries);
+ if (!(hnd = cm_get_sam_dom_handle(ent->domain->name)))
+ break;
+
+ status = cli_samr_enum_dom_groups(
+ hnd->cli, hnd->cli->mem_ctx, hnd->pol,
+ &ent->grp_query_start_ndx,
+ 0x8000, /* buffer size? */
+ (struct acct_info **) &sam_grp_entries, &num_entries);
/* Copy entries into return buffer */
@@ -983,3 +988,5 @@ enum winbindd_result winbindd_getgroups(struct winbindd_cli_state *state)
return result;
}
+
+#endif
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 262a9d7a33..406b12c9f6 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -55,7 +55,7 @@ static void parse_domain_user(char *domuser, fstring domain, fstring user)
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
{
NTSTATUS result;
- fstring name_domain, name_user;
+ fstring name_domain, name_user, auth_dc;
int passlen;
unsigned char trust_passwd[16];
time_t last_change_time;
@@ -127,12 +127,18 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ if (!cm_get_dc_name(lp_workgroup(), auth_dc)) {
+ DEBUG(3, ("Could not find dc for workgroup %s\n",
+ lp_workgroup()));
+ return WINBINDD_ERROR;
+ }
+
/* So domain_client_validate() actually opens a new connection
for each authentication performed. This can theoretically
be optimised to use an already open IPC$ connection. */
result = domain_client_validate(&user_info, &server_info,
- server_state.controller, trust_passwd,
+ auth_dc, trust_passwd,
last_change_time);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
@@ -143,7 +149,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
{
NTSTATUS result;
- fstring name_domain, name_user;
+ fstring name_domain, name_user, auth_dc;
unsigned char trust_passwd[16];
time_t last_change_time;
auth_usersupplied_info user_info;
@@ -198,12 +204,18 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
}
+ if (!cm_get_dc_name(lp_workgroup(), auth_dc)) {
+ DEBUG(3, ("Could not find dc for workgroup %s\n",
+ lp_workgroup()));
+ return WINBINDD_ERROR;
+ }
+
/* So domain_client_validate() actually opens a new connection
for each authentication performed. This can theoretically
be optimised to use an already open IPC$ connection. */
result = domain_client_validate(&user_info, &server_info,
- server_state.controller, trust_passwd,
+ auth_dc, trust_passwd,
last_change_time);
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h
index 8753d7becb..7b4e36576d 100644
--- a/source3/nsswitch/winbindd_proto.h
+++ b/source3/nsswitch/winbindd_proto.h
@@ -45,6 +45,15 @@ BOOL winbindd_fetch_gid_cache_entry(char *domain_name, gid_t gid,
void winbindd_flush_cache(void);
void winbindd_cache_dump_status(void);
+/* The following definitions come from nsswitch/winbindd_cm.c */
+
+BOOL cm_get_dc_name(char *domain, fstring srv_name);
+CLI_POLICY_HND *cm_get_lsa_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_dom_handle(char *domain);
+CLI_POLICY_HND *cm_get_sam_user_handle(char *domain, char *user);
+CLI_POLICY_HND *cm_get_sam_group_handle(char *domain, char *group);
+
/* The following definitions come from nsswitch/winbindd_group.c */
enum winbindd_result winbindd_getgrnam_from_group(struct winbindd_cli_state
@@ -73,8 +82,8 @@ BOOL winbindd_idmap_init(void);
void winbindd_idmap_dump_status(void);
/* The following definitions come from nsswitch/winbindd_misc.c */
-enum winbindd_result winbindd_check_machine_acct(
- struct winbindd_cli_state *state);
+
+enum winbindd_result winbindd_check_machine_acct(struct winbindd_cli_state *state);
enum winbindd_result winbindd_list_trusted_domains(struct winbindd_cli_state
*state);
@@ -106,7 +115,6 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state);
/* The following definitions come from nsswitch/winbindd_util.c */
-void debug_conn_state(void);
BOOL domain_handles_open(struct winbindd_domain *domain);
void winbindd_kill_all_connections(void);
void establish_connections(BOOL force_reestablish) ;
@@ -121,8 +129,6 @@ BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
uint32 user_rid, uint32 *num_groups,
DOM_GID **user_groups);
-BOOL winbindd_lookup_groupinfo(struct winbindd_domain *domain,
- uint32 group_rid, GROUP_INFO_CTR *info);
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
@@ -131,10 +137,9 @@ struct winbindd_domain *find_domain_from_name(char *domain_name);
struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
void free_getent_state(struct getent_state *state);
BOOL winbindd_param_init(void);
-char *winbindd_cmd_to_string(enum winbindd_cmd cmd);
-uint32 domain_sequence_number(char *domain_name);
NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
- uint32 *start_ndx, uint16 info_level,
- uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
+ uint32 *start_ndx, uint16 info_level,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
BOOL check_domain_env(char *domain_env, char *domain);
+void parse_domain_user(char *domuser, fstring domain, fstring user);
#endif /* _PROTO_H_ */
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index aa138cfdeb..bb5b1e354e 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -98,7 +98,6 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
SAM_USERINFO_CTR *user_info;
DOM_SID user_sid;
fstring name_domain, name_user, name, gecos_name;
- struct winbindd_domain *domain;
enum SID_NAME_USE name_type;
DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
@@ -116,18 +115,6 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- /* Get info for the domain */
-
- if ((domain = find_domain_from_name(name_domain)) == NULL) {
- DEBUG(0, ("could not find domain entry for domain %s\n",
- name_domain));
- return WINBINDD_ERROR;
- }
-
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
- }
-
/* Check for cached user entry */
if (winbindd_fetch_user_cache_entry(name_domain, name_user,
@@ -158,6 +145,8 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
/* The following costs 3 packets */
+#if 0
+
if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
DEBUG(1, ("pwnam_from_user(): error getting user info for "
"user '%s'\n", name_user));
@@ -167,10 +156,15 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
group_rid = user_info->info.id21->group_rid;
unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
sizeof(gecos_name) - 1);
+
+#endif
+
+ group_rid = DOMAIN_GROUP_RID_GUESTS;
+ fstrcpy(gecos_name, "foo");
/* Now take all this information and fill in a passwd structure */
- if (!winbindd_fill_pwent(domain->name, state->request.data.username,
+ if (!winbindd_fill_pwent(name_domain, state->request.data.username,
user_rid, group_rid, gecos_name,
&state->response.data.pw)) {
return WINBINDD_ERROR;
@@ -214,10 +208,6 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
return WINBINDD_ERROR;
}
- if (!domain_handles_open(domain)) {
- return WINBINDD_ERROR;
- }
-
/* Check for cached uid entry */
if (winbindd_fetch_uid_cache_entry(domain->name,
@@ -246,6 +236,8 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
/* Get some user info */
+#if 0
+
if (!winbindd_lookup_userinfo(domain, user_rid, &user_info)) {
DEBUG(1, ("pwnam_from_uid(): error getting user info for "
"user '%s'\n", user_name));
@@ -255,6 +247,10 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
group_rid = user_info->info.id21->group_rid;
unistr2_to_ascii(gecos_name, &user_info->info.id21->uni_full_name,
sizeof(gecos_name) - 1);
+#endif
+
+ group_rid = DOMAIN_GROUP_RID_GUESTS;
+ fstrcpy(gecos_name, "foo");
/* Resolve gid number */
@@ -276,6 +272,8 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
return WINBINDD_OK;
}
+#if 0
+
/*
* set/get/endpwent functions
*/
@@ -694,3 +692,5 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
return WINBINDD_OK;
}
+
+#endif
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 86517c4e2d..c5b3c7585b 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -24,26 +24,9 @@
#include "winbindd.h"
#include "sids.h"
-static void winbindd_kill_connections(struct winbindd_domain *domain);
-
-/* Debug connection state */
-
-void debug_conn_state(void)
-{
- struct winbindd_domain *domain;
-
- DEBUG(3, ("server: dc=%s, pwdb_init=%d, lsa_hnd=%d\n",
- server_state.controller,
- server_state.pwdb_initialised,
- server_state.lsa_handle_open));
+#if 0
- for (domain = domain_list; domain; domain = domain->next) {
- DEBUG(3, ("%s: dc=%s, got_sid=%d, sam_hnd=%d sam_dom_hnd=%d\n",
- domain->name, domain->controller,
- domain->got_domain_info, domain->sam_handle_open,
- domain->sam_dom_handle_open));
- }
-}
+static void winbindd_kill_connections(struct winbindd_domain *domain);
/* Add a trusted domain to our list of domains */
@@ -187,7 +170,6 @@ BOOL domain_handles_open(struct winbindd_domain *domain)
}
DEBUG(3, ("checking domain handles for domain %s\n", domain->name));
- debug_conn_state();
domain->last_check = t;
@@ -246,8 +228,6 @@ static void winbindd_kill_connections(struct winbindd_domain *domain)
DEBUG(0, ("killing connections to domain %s with controller %s\n",
domain->name, domain->controller));
- debug_conn_state();
-
/* Close LSA connections if we are killing connections to the dc
that has them open. */
@@ -303,37 +283,6 @@ void winbindd_kill_all_connections(void)
}
}
-static BOOL get_any_dc_name(char *domain, fstring srv_name)
-{
- struct in_addr *ip_list, dc_ip;
- extern pstring global_myname;
- int count, i;
-
- /* Lookup domain controller name */
-
- if (!get_dc_list(False, domain, &ip_list, &count))
- return False;
-
- /* Firstly choose a PDC/BDC who has the same network address as any
- of our interfaces. */
-
- for (i = 0; i < count; i++) {
- if(!is_local_net(ip_list[i]))
- goto got_ip;
- }
-
- i = (sys_random() % count);
-
- got_ip:
- dc_ip = ip_list[i];
- SAFE_FREE(ip_list);
-
- if (!lookup_pdc_name(global_myname, domain, &dc_ip, srv_name))
- return False;
-
- return True;
-}
-
/* Attempt to connect to all domain controllers we know about */
void establish_connections(BOOL force_reestablish)
@@ -350,7 +299,6 @@ void establish_connections(BOOL force_reestablish)
lastt = t;
DEBUG(3, ("establishing connections\n"));
- debug_conn_state();
/* Maybe the connection died - if so then close up and restart */
@@ -401,96 +349,88 @@ void establish_connections(BOOL force_reestablish)
get_trusted_domains();
}
-
- debug_conn_state();
}
+#endif
+
/* Connect to a domain controller using get_any_dc_name() to discover
the domain name and sid */
BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
{
- fstring level5_dom;
- BOOL res;
- uint32 enum_ctx = 0;
- uint32 num_doms = 0;
- char **domains = NULL;
- DOM_SID *sids = NULL;
-
- if (domain == NULL) {
- return False;
- }
-
- DEBUG(1, ("looking up sid for domain %s\n", domain_name));
-
- /* Get controller name for domain */
-
- if (!get_any_dc_name(domain_name, domain->controller)) {
- DEBUG(0, ("Could not resolve domain controller for domain %s\n",
- domain_name));
- return False;
- }
-
- /* Do a level 5 query info policy if we are looking up our own SID */
-
- if (strequal(domain_name, lp_workgroup())) {
- return wb_lsa_query_info_pol(&server_state.lsa_handle, 0x05,
- level5_dom, &domain->sid);
- }
-
- /* Use lsaenumdomains to get sid for this domain */
-
- res = wb_lsa_enum_trust_dom(&server_state.lsa_handle, &enum_ctx,
- &num_doms, &domains, &sids);
-
- /* Look for domain name */
-
- if (res && domains && sids) {
- int found = False;
- int i;
-
- for(i = 0; i < num_doms; i++) {
- if (strequal(domain_name, domains[i])) {
- sid_copy(&domain->sid, &sids[i]);
- found = True;
+ fstring level5_dom;
+ uint32 enum_ctx = 0;
+ uint32 num_doms = 0;
+ char **domains = NULL;
+ DOM_SID *sids = NULL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+
+ DEBUG(1, ("looking up sid for domain %s\n", domain_name));
+
+ if (!(hnd = cm_get_lsa_handle(domain_name)))
+ return False;
+
+ /* Do a level 5 query info policy if we are looking up the SID for
+ our own domain. */
+
+ if (strequal(domain_name, lp_workgroup())) {
+
+ result = cli_lsa_query_info_policy(hnd->cli, hnd->cli->mem_ctx,
+ &hnd->pol, 0x05, level5_dom,
+ &domain->sid);
+
+ return NT_STATUS_IS_OK(result);
+ }
+
+ /* Use lsaenumdomains to get sid for this domain */
+
+ result = cli_lsa_enum_trust_dom(hnd->cli, hnd->cli->mem_ctx, &hnd->pol,
+ &enum_ctx, &num_doms, &domains, &sids);
+
+ /* Look for domain name */
+
+ if (NT_STATUS_IS_OK(result) && domains && sids) {
+ int found = False;
+ int i;
+
+ for(i = 0; i < num_doms; i++) {
+ if (strequal(domain_name, domains[i])) {
+ sid_copy(&domain->sid, &sids[i]);
+ found = True;
break;
- }
- }
-
- res = found;
- }
-
- return res;
+ }
+ }
+
+ return found;
+ }
+
+ return NT_STATUS_IS_OK(result);
}
/* Lookup domain controller and sid for a domain */
BOOL get_domain_info(struct winbindd_domain *domain)
{
- fstring sid_str;
-
- DEBUG(1, ("Getting domain info for domain %s\n", domain->name));
-
- /* Lookup domain sid */
-
- if (!lookup_domain_sid(domain->name, domain)) {
- DEBUG(0, ("could not find sid for domain %s\n", domain->name));
-
- /* Could be a DC failure - shut down connections to this domain */
-
- winbindd_kill_connections(domain);
-
- return False;
- }
-
- /* Lookup OK */
-
- domain->got_domain_info = 1;
+ fstring sid_str;
+
+ DEBUG(1, ("Getting domain info for domain %s\n", domain->name));
- sid_to_string(sid_str, &domain->sid);
- DEBUG(1, ("found sid %s for domain %s\n", sid_str, domain->name));
+ /* Lookup domain sid */
+
+ if (!lookup_domain_sid(domain->name, domain)) {
+ DEBUG(0, ("could not find sid for domain %s\n", domain->name));
+ return False;
+ }
+
+ /* Lookup OK */
- return True;
+ domain->got_domain_info = 1;
+
+ sid_to_string(sid_str, &domain->sid);
+ DEBUG(1, ("found sid %s for domain %s\n", sid_str, domain->name));
+
+ return True;
}
/* Lookup a sid in a domain from a name */
@@ -498,40 +438,44 @@ BOOL get_domain_info(struct winbindd_domain *domain)
BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
enum SID_NAME_USE *type)
{
- int num_sids = 0, num_names = 1;
- DOM_SID *sids = NULL;
- uint32 *types = NULL;
- BOOL res;
-
- /* Don't bother with machine accounts */
-
- if (name[strlen(name) - 1] == '$') {
- return False;
- }
-
- /* Lookup name */
-
- res = wb_lsa_lookup_names(&server_state.lsa_handle, num_names,
- (char **)&name, &sids, &types, &num_sids);
-
- /* 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];
+ int num_sids = 0, num_names = 1;
+ DOM_SID *sids = NULL;
+ uint32 *types = NULL;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+
+ /* Don't bother with machine accounts */
+
+ if (name[strlen(name) - 1] == '$')
+ return False;
+
+ /* Lookup name */
+
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ return False;
+
+ result = cli_lsa_lookup_names(hnd->cli, hnd->cli->mem_ctx, &hnd->pol,
+ num_names, (char **)&name, &sids,
+ &types, &num_sids);
+
+ /* Return rid and type if lookup successful */
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ /* Return sid */
+
+ if ((sid != NULL) && (sids != NULL))
+ sid_copy(sid, &sids[0]);
+
+ /* Return name type */
+
+ if ((type != NULL) && (types != NULL))
+ *type = types[0];
+
+ return True;
}
- }
-
- return res;
+
+ return False;
}
/* Lookup a name in a domain from a sid */
@@ -539,36 +483,43 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
enum SID_NAME_USE *type)
{
- int num_sids = 1, num_names = 0;
- uint32 *types = NULL;
- char **names;
- BOOL res;
-
- /* Lookup name */
-
- res = wb_lsa_lookup_sids(&server_state.lsa_handle, num_sids, sid,
- &names, &types, &num_names);
-
- /* Return name and type if successful */
-
- if (res) {
-
- /* Return name */
-
- if ((names != NULL) && (name != NULL)) {
- fstrcpy(name, names[0]);
- }
-
- /* Return name type */
+ int num_sids = 1, num_names = 0;
+ uint32 *types = NULL;
+ char **names;
+ CLI_POLICY_HND *hnd;
+ NTSTATUS result;
+
+ /* Lookup name */
+
+ if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
+ return False;
+
+ result = cli_lsa_lookup_sids(hnd->cli, hnd->cli->mem_ctx, &hnd->pol,
+ num_sids, sid, &names, &types,
+ &num_names);
- if ((type != NULL) && (types != NULL)) {
- *type = types[0];
+ /* Return name and type if successful */
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ /* Return name */
+
+ if ((names != NULL) && (name != NULL))
+ fstrcpy(name, names[0]);
+
+ /* Return name type */
+
+ if ((type != NULL) && (types != NULL))
+ *type = types[0];
+
+ return True;
}
- }
-
- return res;
+
+ return False;
}
+#if 0
+
/* Lookup user information from a rid */
BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain,
@@ -620,6 +571,8 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
num_names, rid_mem, names, name_types);
}
+#endif
+
/* Globals for domain list stuff */
struct winbindd_domain *domain_list = NULL;
@@ -751,31 +704,7 @@ BOOL winbindd_param_init(void)
return True;
}
-/* find the sequence number for a domain */
-
-uint32 domain_sequence_number(char *domain_name)
-{
- struct winbindd_domain *domain;
- SAM_UNK_CTR ctr;
-
- domain = find_domain_from_name(domain_name);
- if (!domain) return DOM_SEQUENCE_NONE;
-
- if (!wb_samr_query_dom_info(&domain->sam_dom_handle, 2, &ctr)) {
-
- /* If this fails, something bad has gone wrong */
-
- winbindd_kill_connections(domain);
-
- DEBUG(2,("domain sequence query failed\n"));
- return DOM_SEQUENCE_NONE;
- }
-
- DEBUG(4,("got domain sequence number for %s of %u\n",
- domain_name, (unsigned)ctr.info.inf2.seq_num));
-
- return ctr.info.inf2.seq_num;
-}
+#if 0
/* Query display info for a domain. This returns enough information plus a
bit extra to give an overview of domain users for the User Manager
@@ -805,6 +734,7 @@ BOOL check_domain_env(char *domain_env, char *domain)
return False;
}
+#endif
/* Parse a string of the form DOMAIN/user into a domain and a user */