mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
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 commit is contained in:
parent
880201b52b
commit
c369cf5af7
@ -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;
|
||||
}
|
||||
|
||||
} 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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
/* Create the socket file */
|
||||
|
||||
old_umask = umask(0);
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
|
||||
if (sock == -1) {
|
||||
perror("socket");
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
{
|
||||
|
245
source/nsswitch/winbindd_cm.c
Normal file
245
source/nsswitch/winbindd_cm.c
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -24,27 +24,10 @@
|
||||
#include "winbindd.h"
|
||||
#include "sids.h"
|
||||
|
||||
#if 0
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/* Add a trusted domain to our list of domains */
|
||||
|
||||
static struct winbindd_domain *add_trusted_domain(char *domain_name)
|
||||
@ -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;
|
||||
fstring sid_str;
|
||||
|
||||
DEBUG(1, ("Getting domain info for domain %s\n", domain->name));
|
||||
|
||||
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));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Lookup OK */
|
||||
|
||||
/* 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;
|
||||
|
||||
sid_to_string(sid_str, &domain->sid);
|
||||
DEBUG(1, ("found sid %s for domain %s\n", sid_str, domain->name));
|
||||
|
||||
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;
|
||||
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];
|
||||
|
||||
/* Don't bother with machine accounts */
|
||||
|
||||
if (name[strlen(name) - 1] == '$') {
|
||||
return True;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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);
|
||||
|
||||
/* Lookup name */
|
||||
/* 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 */
|
||||
|
||||
res = wb_lsa_lookup_sids(&server_state.lsa_handle, num_sids, sid,
|
||||
&names, &types, &num_names);
|
||||
if ((type != NULL) && (types != NULL))
|
||||
*type = types[0];
|
||||
|
||||
/* Return name and type if successful */
|
||||
|
||||
if (res) {
|
||||
|
||||
/* Return name */
|
||||
|
||||
if ((names != NULL) && (name != NULL)) {
|
||||
fstrcpy(name, names[0]);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Return name type */
|
||||
|
||||
if ((type != NULL) && (types != NULL)) {
|
||||
*type = types[0];
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user