summaryrefslogtreecommitdiff
path: root/source3/winbindd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/winbindd')
-rw-r--r--source3/winbindd/winbindd.c131
-rw-r--r--source3/winbindd/winbindd.h21
-rw-r--r--source3/winbindd/winbindd_async.c753
-rw-r--r--source3/winbindd/winbindd_cm.c11
-rw-r--r--source3/winbindd/winbindd_dual.c40
-rw-r--r--source3/winbindd/winbindd_idmap.c819
-rw-r--r--source3/winbindd/winbindd_locator.c102
-rw-r--r--source3/winbindd/winbindd_misc.c64
-rw-r--r--source3/winbindd/winbindd_pam.c78
-rw-r--r--source3/winbindd/winbindd_sid.c12
-rw-r--r--source3/winbindd/winbindd_sockinit.c126
-rw-r--r--source3/winbindd/winbindd_util.c75
12 files changed, 973 insertions, 1259 deletions
diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c
index 17915fb01b..81f07c4c8c 100644
--- a/source3/winbindd/winbindd.c
+++ b/source3/winbindd/winbindd.c
@@ -7,7 +7,6 @@
Copyright (C) Andrew Tridgell 2002
Copyright (C) Jelmer Vernooij 2003
Copyright (C) Volker Lendecke 2004
- Copyright (C) James Peach 2007
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
@@ -30,6 +29,7 @@
#define DBGC_CLASS DBGC_WINBIND
BOOL opt_nocache = False;
+static BOOL interactive = False;
extern BOOL override_logfile;
@@ -129,8 +129,13 @@ static void flush_caches(void)
static void terminate(void)
{
+ pstring path;
+
+ /* Remove socket file */
+ pstr_sprintf(path, "%s/%s",
+ get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME);
+ unlink(path);
- winbindd_release_sockets();
idmap_close();
trustdom_cache_shutdown();
@@ -791,14 +796,23 @@ static BOOL remove_idle_client(void)
simultaneous connections while remaining impervious to many denial of
service attacks. */
-static int process_loop(int listen_sock, int listen_priv_sock)
+static void process_loop(void)
{
struct winbindd_cli_state *state;
struct fd_event *ev;
fd_set r_fds, w_fds;
- int maxfd, selret;
+ int maxfd, listen_sock, listen_priv_sock, selret;
struct timeval timeout, ev_timeout;
+ /* Open Sockets here to get stuff going ASAP */
+ listen_sock = open_winbindd_socket();
+ listen_priv_sock = open_winbindd_priv_socket();
+
+ if (listen_sock == -1 || listen_priv_sock == -1) {
+ perror("open_winbind_socket");
+ exit(1);
+ }
+
/* We'll be doing this a lot */
/* Handle messages */
@@ -963,58 +977,6 @@ static int process_loop(int listen_sock, int listen_priv_sock)
winbind_child_died(pid);
}
}
-
-
- return winbindd_num_clients();
-}
-
-static void winbindd_process_loop(enum smb_server_mode server_mode)
-{
- int idle_timeout_sec;
- struct timeval starttime;
- int listen_public, listen_priv;
-
- errno = 0;
- if (!winbindd_init_sockets(&listen_public, &listen_priv,
- &idle_timeout_sec)) {
- terminate();
- }
-
- starttime = timeval_current();
-
- if (listen_public == -1 || listen_priv == -1) {
- DEBUG(0, ("failed to open winbindd pipes: %s\n",
- errno ? strerror(errno) : "unknown error"));
- terminate();
- }
-
- for (;;) {
- TALLOC_CTX *frame = talloc_stackframe();
- int clients = process_loop(listen_public, listen_priv);
-
- /* Don't bother figuring out the idle time if we won't be
- * timing out anyway.
- */
- if (idle_timeout_sec < 0) {
- TALLOC_FREE(frame);
- continue;
- }
-
- if (clients == 0 && server_mode == SERVER_MODE_FOREGROUND) {
- struct timeval now;
-
- now = timeval_current();
- if (timeval_elapsed2(&starttime, &now) >
- (double)idle_timeout_sec) {
- DEBUG(0, ("idle for %d secs, exitting\n",
- idle_timeout_sec));
- terminate();
- }
- } else {
- starttime = timeval_current();
- }
- TALLOC_FREE(frame);
- }
}
/* Main function */
@@ -1022,18 +984,17 @@ static void winbindd_process_loop(enum smb_server_mode server_mode)
int main(int argc, char **argv, char **envp)
{
pstring logfile;
- BOOL log_stdout = False;
- BOOL no_process_group = False;
-
- enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
-
+ static BOOL is_daemon = False;
+ static BOOL Fork = True;
+ static BOOL log_stdout = False;
+ static BOOL no_process_group = False;
struct poptOption long_options[] = {
POPT_AUTOHELP
{ "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- { "foreground", 'F', POPT_ARG_VAL, &server_mode, SERVER_MODE_FOREGROUND, "Daemon in foreground mode" },
+ { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" },
{ "no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
- { "daemon", 'D', POPT_ARG_VAL, &server_mode, SERVER_MODE_DAEMON, "Become a daemon (default)" },
- { "interactive", 'i', POPT_ARG_VAL, &server_mode, SERVER_MODE_INTERACTIVE, "Interactive mode" },
+ { "daemon", 'D', POPT_ARG_NONE, NULL, 'D', "Become a daemon (default)" },
+ { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
{ "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" },
POPT_COMMON_SAMBA
POPT_TABLEEND
@@ -1072,6 +1033,15 @@ int main(int argc, char **argv, char **envp)
while ((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
+ /* Don't become a daemon */
+ case 'D':
+ is_daemon = True;
+ break;
+ case 'i':
+ interactive = True;
+ log_stdout = True;
+ Fork = False;
+ break;
default:
d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
poptBadOption(pc, 0), poptStrerror(opt));
@@ -1080,15 +1050,16 @@ int main(int argc, char **argv, char **envp)
}
}
- if (server_mode == SERVER_MODE_INTERACTIVE) {
- log_stdout = True;
- if (DEBUGLEVEL >= 9) {
- talloc_enable_leak_report();
- }
+ if (is_daemon && interactive) {
+ d_fprintf(stderr,"\nERROR: "
+ "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
+ poptPrintUsage(pc, stderr, 0);
+ exit(1);
}
- if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
- printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
+ if (log_stdout && Fork) {
+ d_fprintf(stderr, "\nERROR: "
+ "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
poptPrintUsage(pc, stderr, 0);
exit(1);
}
@@ -1161,12 +1132,8 @@ int main(int argc, char **argv, char **envp)
CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
CatchSignal(SIGHUP, sighup_handler);
- if (server_mode == SERVER_MODE_DAEMON) {
- DEBUG( 3, ( "Becoming a daemon.\n" ) );
- become_daemon(True, no_process_group);
- } else if (server_mode == SERVER_MODE_FOREGROUND) {
- become_daemon(False, no_process_group);
- }
+ if (!interactive)
+ become_daemon(Fork, no_process_group);
pidfile_create("winbindd");
@@ -1189,9 +1156,8 @@ int main(int argc, char **argv, char **envp)
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group) {
+ if (interactive && !no_process_group)
setpgid( (pid_t)0, (pid_t)0);
- }
#endif
TimeInit();
@@ -1248,7 +1214,12 @@ int main(int argc, char **argv, char **envp)
smb_nscd_flush_group_cache();
/* Loop waiting for requests */
- winbindd_process_loop(server_mode);
+
+ while (1) {
+ TALLOC_CTX *frame = talloc_stackframe();
+ process_loop();
+ TALLOC_FREE(frame);
+ }
return 0;
}
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index d61254af4a..ebede0f007 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -134,17 +134,6 @@ struct winbindd_async_request;
/* Async child */
-struct winbindd_domain;
-
-struct winbindd_child_dispatch_table {
- enum winbindd_cmd cmd;
- enum winbindd_result (*fn)(struct winbindd_domain *domain,
- struct winbindd_cli_state *state);
- const char *winbindd_cmd_name;
-};
-
-extern const struct winbindd_child_dispatch_table domain_dispatch_table[];
-
struct winbindd_child {
struct winbindd_child *next, *prev;
@@ -155,8 +144,6 @@ struct winbindd_child {
struct fd_event event;
struct timed_event *lockout_policy_event;
struct winbindd_async_request *requests;
-
- const struct winbindd_child_dispatch_table *table;
};
/* Structures to hold per domain information */
@@ -178,14 +165,6 @@ struct winbindd_domain {
time_t startup_time; /* When we set "startup" true. */
BOOL startup; /* are we in the first 30 seconds after startup_time ? */
- BOOL can_do_samlogon_ex; /* Due to the lack of finer control what type
- * of DC we have, let us try to do a
- * credential-chain less samlogon_ex call
- * with AD and schannel. If this fails with
- * DCERPC_FAULT_OP_RNG_ERROR, then set this
- * to False. This variable is around so that
- * we don't have to try _ex every time. */
-
/* Lookup methods for this domain (LDAP or RPC) */
struct winbindd_methods *methods;
diff --git a/source3/winbindd/winbindd_async.c b/source3/winbindd/winbindd_async.c
index 00c20529c5..5d31ff0a41 100644
--- a/source3/winbindd/winbindd_async.c
+++ b/source3/winbindd/winbindd_async.c
@@ -57,12 +57,12 @@ static void do_async_recv(void *private_data, BOOL success)
state->c, state->private_data);
}
-void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
- const struct winbindd_request *request,
- void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data),
- void *c, void *private_data)
+static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
+ const struct winbindd_request *request,
+ void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data),
+ void *c, void *private_data)
{
struct do_async_state *state;
@@ -111,6 +111,581 @@ void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
&state->response, do_async_recv, state);
}
+static void winbindd_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger idmap_set_mapping\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap_set_mapping returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
+ void (*cont)(void *private_data, BOOL success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SET_MAPPING;
+ request.data.dual_idmapset.id = map->xid.id;
+ request.data.dual_idmapset.type = map->xid.type;
+ sid_to_string(request.data.dual_idmapset.sid, map->sid);
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_set_mapping_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct id_map map;
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: dual_idmapset\n", (unsigned long)state->pid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
+ return WINBINDD_ERROR;
+
+ map.sid = &sid;
+ map.xid.id = state->request.data.dual_idmapset.id;
+ map.xid.type = state->request.data.dual_idmapset.type;
+ map.status = ID_MAPPED;
+
+ result = idmap_set_mapping(&map);
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
+static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger idmap_set_hwm\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap_set_hwm returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
+ void (*cont)(void *private_data, BOOL success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SET_HWM;
+ request.data.dual_idmapset.id = xid->id;
+ request.data.dual_idmapset.type = xid->type;
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_set_hwm_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct unixid xid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: dual_set_hwm\n", (unsigned long)state->pid));
+
+ xid.id = state->request.data.dual_idmapset.id;
+ xid.type = state->request.data.dual_idmapset.type;
+
+ switch (xid.type) {
+ case ID_TYPE_UID:
+ result = idmap_set_uid_hwm(&xid);
+ break;
+ case ID_TYPE_GID:
+ result = idmap_set_gid_hwm(&xid);
+ break;
+ default:
+ return WINBINDD_ERROR;
+ }
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
+static void winbindd_sids2xids_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, void *, int) =
+ (void (*)(void *, BOOL, void *, int))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger sids2xids\n"));
+ cont(private_data, False, NULL, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("sids2xids returned an error\n"));
+ cont(private_data, False, NULL, 0);
+ return;
+ }
+
+ cont(private_data, True, response->extra_data.data, response->length - sizeof(response));
+}
+
+void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size,
+ void (*cont)(void *private_data, BOOL success, void *data, int len),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SIDS2XIDS;
+ request.extra_data.data = (char *)sids;
+ request.extra_len = size;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID *sids;
+ struct unixid *xids;
+ struct id_map **ids;
+ NTSTATUS result;
+ int num, i;
+
+ DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid));
+
+ if (state->request.extra_len == 0) {
+ DEBUG(0, ("Invalid buffer size!\n"));
+ return WINBINDD_ERROR;
+ }
+
+ sids = (DOM_SID *)state->request.extra_data.data;
+ num = state->request.extra_len / sizeof(DOM_SID);
+
+ ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1);
+ if ( ! ids) {
+ DEBUG(0, ("Out of memory!\n"));
+ return WINBINDD_ERROR;
+ }
+ for (i = 0; i < num; i++) {
+ ids[i] = TALLOC_P(ids, struct id_map);
+ if ( ! ids[i]) {
+ DEBUG(0, ("Out of memory!\n"));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+ ids[i]->sid = &sids[i];
+ }
+
+ result = idmap_sids_to_unixids(ids);
+
+ if (NT_STATUS_IS_OK(result)) {
+
+ xids = SMB_MALLOC_ARRAY(struct unixid, num);
+ if ( ! xids) {
+ DEBUG(0, ("Out of memory!\n"));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+
+ for (i = 0; i < num; i++) {
+ if (ids[i]->status == ID_MAPPED) {
+ xids[i].type = ids[i]->xid.type;
+ xids[i].id = ids[i]->xid.id;
+ } else {
+ xids[i].type = -1;
+ }
+ }
+
+ state->response.length = sizeof(state->response) + (sizeof(struct unixid) * num);
+ state->response.extra_data.data = xids;
+
+ } else {
+ DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result)));
+ talloc_free(ids);
+ return WINBINDD_ERROR;
+ }
+
+ talloc_free(ids);
+ return WINBINDD_OK;
+}
+
+static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, uid_t uid) =
+ (void (*)(void *, BOOL, uid_t))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger sid2uid\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("sid2uid returned an error\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ cont(private_data, True, response->data.uid);
+}
+
+void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ void (*cont)(void *private_data, BOOL success, uid_t uid),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SID2UID;
+ sid_to_string(request.data.dual_sid2id.sid, sid);
+ do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
+ state->request.data.dual_sid2id.sid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.dual_sid2id.sid));
+ return WINBINDD_ERROR;
+ }
+
+ /* Find uid for this sid and return it, possibly ask the slow remote idmap */
+
+ result = idmap_sid_to_uid(&sid, &(state->response.data.uid));
+
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
+#if 0 /* not used */
+static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data);
+
+void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid,
+ void (*cont)(void *private_data, BOOL success,
+ const char *name),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_UID2NAME;
+ request.data.uid = uid;
+ do_async(mem_ctx, idmap_child(), &request, uid2name_recv,
+ (void *)cont, private_data);
+}
+#endif /* not used */
+
+enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct passwd *pw;
+
+ DEBUG(3, ("[%5lu]: uid2name %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.uid));
+
+ pw = getpwuid(state->request.data.uid);
+ if (pw == NULL) {
+ DEBUG(5, ("User %lu not found\n",
+ (unsigned long)state->request.data.uid));
+ return WINBINDD_ERROR;
+ }
+
+ fstrcpy(state->response.data.name.name, pw->pw_name);
+ return WINBINDD_OK;
+}
+
+#if 0 /* not used */
+static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *name) =
+ (void (*)(void *, BOOL, const char *))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger uid2name\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("uid2name returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.name.name);
+}
+
+static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data);
+
+static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name,
+ void (*cont)(void *private_data, BOOL success,
+ uid_t uid),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_NAME2UID;
+ fstrcpy(request.data.username, name);
+ do_async(mem_ctx, idmap_child(), &request, name2uid_recv,
+ (void *)cont, private_data);
+}
+#endif /* not used */
+
+enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct passwd *pw;
+
+ /* Ensure null termination */
+ state->request.data.username
+ [sizeof(state->request.data.username)-1] = '\0';
+
+ DEBUG(3, ("[%5lu]: name2uid %s\n", (unsigned long)state->pid,
+ state->request.data.username));
+
+ pw = getpwnam(state->request.data.username);
+ if (pw == NULL) {
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.uid = pw->pw_uid;
+ return WINBINDD_OK;
+}
+
+#if 0 /* not used */
+static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, uid_t uid) =
+ (void (*)(void *, BOOL, uid_t))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger name2uid\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("name2uid returned an error\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ cont(private_data, True, response->data.uid);
+}
+#endif /* not used */
+
+static void winbindd_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, gid_t gid) =
+ (void (*)(void *, BOOL, gid_t))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger sid2gid\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("sid2gid returned an error\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ cont(private_data, True, response->data.gid);
+}
+
+void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+ void (*cont)(void *private_data, BOOL success, gid_t gid),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_SID2GID;
+ sid_to_string(request.data.dual_sid2id.sid, sid);
+
+ DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
+ request.data.dual_sid2id.sid));
+
+ do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
+ state->request.data.dual_sid2id.sid));
+
+ if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
+ DEBUG(1, ("Could not get convert sid %s from string\n",
+ state->request.data.dual_sid2id.sid));
+ return WINBINDD_ERROR;
+ }
+
+ /* Find gid for this sid and return it, possibly ask the slow remote idmap */
+
+ result = idmap_sid_to_gid(&sid, &state->response.data.gid);
+
+ DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", NT_STATUS_V(result), sid_string_static(&sid), state->response.data.gid));
+
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
+
+static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *name) =
+ (void (*)(void *, BOOL, const char *))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger gid2name\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("gid2name returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.name.name);
+}
+
+void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid,
+ void (*cont)(void *private_data, BOOL success,
+ const char *name),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_GID2NAME;
+ request.data.gid = gid;
+ do_async(mem_ctx, idmap_child(), &request, gid2name_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct group *gr;
+
+ DEBUG(3, ("[%5lu]: gid2name %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.gid));
+
+ gr = getgrgid(state->request.data.gid);
+ if (gr == NULL)
+ return WINBINDD_ERROR;
+
+ fstrcpy(state->response.data.name.name, gr->gr_name);
+ return WINBINDD_OK;
+}
+
+#if 0 /* not used */
+static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data);
+
+static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name,
+ void (*cont)(void *private_data, BOOL success,
+ gid_t gid),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_NAME2GID;
+ fstrcpy(request.data.groupname, name);
+ do_async(mem_ctx, idmap_child(), &request, name2gid_recv,
+ (void *)cont, private_data);
+}
+#endif /* not used */
+
+enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ struct group *gr;
+
+ /* Ensure null termination */
+ state->request.data.groupname
+ [sizeof(state->request.data.groupname)-1] = '\0';
+
+ DEBUG(3, ("[%5lu]: name2gid %s\n", (unsigned long)state->pid,
+ state->request.data.groupname));
+
+ gr = getgrnam(state->request.data.groupname);
+ if (gr == NULL) {
+ return WINBINDD_ERROR;
+ }
+
+ state->response.data.gid = gr->gr_gid;
+ return WINBINDD_OK;
+}
+
+#if 0 /* not used */
+static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, gid_t gid) =
+ (void (*)(void *, BOOL, gid_t))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger name2gid\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("name2gid returned an error\n"));
+ cont(private_data, False, 0);
+ return;
+ }
+
+ cont(private_data, True, response->data.gid);
+}
+#endif /* not used */
+
struct lookupsid_state {
DOM_SID sid;
void *caller_private_data;
@@ -952,3 +1527,169 @@ void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
do_async_domain(mem_ctx, domain, &request, query_user_recv,
(void *)cont, private_data);
}
+
+/* The following uid2sid/gid2sid functions has been contributed by
+ * Keith Reynolds <Keith.Reynolds@centrify.com> */
+
+static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *sid) =
+ (void (*)(void *, BOOL, const char *))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger uid2sid\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("uid2sid returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.sid.sid);
+}
+
+void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
+ void (*cont)(void *private_data, BOOL success, const char *sid),
+ void *private_data)
+{
+ struct winbindd_request request;
+
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_UID2SID;
+ request.data.uid = uid;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3,("[%5lu]: uid to sid %lu\n",
+ (unsigned long)state->pid,
+ (unsigned long) state->request.data.uid));
+
+ /* Find sid for this uid and return it, possibly ask the slow remote idmap */
+ result = idmap_uid_to_sid(&sid, state->request.data.uid);
+
+ if (NT_STATUS_IS_OK(result)) {
+ sid_to_string(state->response.data.sid.sid, &sid);
+ state->response.data.sid.type = SID_NAME_USER;
+ return WINBINDD_OK;
+ }
+
+ return WINBINDD_ERROR;
+}
+
+static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *sid) =
+ (void (*)(void *, BOOL, const char *))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger gid2sid\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("gid2sid returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.sid.sid);
+}
+
+void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
+ void (*cont)(void *private_data, BOOL success, const char *sid),
+ void *private_data)
+{
+ struct winbindd_request request;
+
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_GID2SID;
+ request.data.gid = gid;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3,("[%5lu]: gid %lu to sid\n",
+ (unsigned long)state->pid,
+ (unsigned long) state->request.data.gid));
+
+ /* Find sid for this gid and return it, possibly ask the slow remote idmap */
+ result = idmap_gid_to_sid(&sid, state->request.data.gid);
+
+ if (NT_STATUS_IS_OK(result)) {
+ sid_to_string(state->response.data.sid.sid, &sid);
+ DEBUG(10, ("[%5lu]: retrieved sid: %s\n",
+ (unsigned long)state->pid,
+ state->response.data.sid.sid));
+ state->response.data.sid.type = SID_NAME_DOM_GRP;
+ return WINBINDD_OK;
+ }
+
+ return WINBINDD_ERROR;
+}
+
+static void winbindd_dump_id_maps_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ) =
+ (void (*)(void *, BOOL))c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger a map dump\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("idmap dump maps returned an error\n"));
+ cont(private_data, False);
+ return;
+ }
+
+ cont(private_data, True);
+}
+
+void winbindd_dump_maps_async(TALLOC_CTX *mem_ctx, void *data, int size,
+ void (*cont)(void *private_data, BOOL success),
+ void *private_data)
+{
+ struct winbindd_request request;
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_DUMP_MAPS;
+ request.extra_data.data = (char *)data;
+ request.extra_len = size;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_dump_id_maps_recv,
+ (void *)cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_dump_maps(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DEBUG(3, ("[%5lu]: dual dump maps\n", (unsigned long)state->pid));
+
+ idmap_dump_maps((char *)state->request.extra_data.data);
+
+ return WINBINDD_OK;
+}
+
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 9ffb3dfb23..e12b13cbbd 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -2224,12 +2224,6 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
no_schannel:
if ((lp_client_schannel() == False) ||
((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
-
- /*
- * NetSamLogonEx only works for schannel
- */
- domain->can_do_samlogon_ex = False;
-
/* We're done - just keep the existing connection to NETLOGON
* open */
conn->netlogon_pipe = netlogon_pipe;
@@ -2261,11 +2255,6 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
}
- /*
- * Try NetSamLogonEx for AD domains
- */
- domain->can_do_samlogon_ex = domain->active_directory;
-
*cli = conn->netlogon_pipe;
return NT_STATUS_OK;
}
diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c
index 7e53fbbbee..d9a42c31dc 100644
--- a/source3/winbindd/winbindd_dual.c
+++ b/source3/winbindd/winbindd_dual.c
@@ -408,14 +408,23 @@ void sendto_domain(struct winbindd_cli_state *state,
recvfrom_child, state);
}
-const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
+struct winbindd_child_dispatch_table {
+ enum winbindd_cmd cmd;
+ enum winbindd_result (*fn)(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state);
+ const char *winbindd_cmd_name;
+};
+
+static struct winbindd_child_dispatch_table child_dispatch_table[] = {
+
{ WINBINDD_LOOKUPSID, winbindd_dual_lookupsid, "LOOKUPSID" },
{ WINBINDD_LOOKUPNAME, winbindd_dual_lookupname, "LOOKUPNAME" },
{ WINBINDD_LOOKUPRIDS, winbindd_dual_lookuprids, "LOOKUPRIDS" },
{ WINBINDD_LIST_TRUSTDOM, winbindd_dual_list_trusted_domains, "LIST_TRUSTDOM" },
{ WINBINDD_INIT_CONNECTION, winbindd_dual_init_connection, "INIT_CONNECTION" },
{ WINBINDD_GETDCNAME, winbindd_dual_getdcname, "GETDCNAME" },
+ { WINBINDD_DSGETDCNAME, winbindd_dual_dsgetdcname, "DSGETDCNAME" },
{ WINBINDD_SHOW_SEQUENCE, winbindd_dual_show_sequence, "SHOW_SEQUENCE" },
{ WINBINDD_PAM_AUTH, winbindd_dual_pam_auth, "PAM_AUTH" },
{ WINBINDD_PAM_AUTH_CRAP, winbindd_dual_pam_auth_crap, "AUTH_CRAP" },
@@ -423,7 +432,23 @@ const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
{ WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,winbindd_dual_pam_chng_pswd_auth_crap,"CHNG_PSWD_AUTH_CRAP" },
{ WINBINDD_PAM_CHAUTHTOK, winbindd_dual_pam_chauthtok, "PAM_CHAUTHTOK" },
{ WINBINDD_CHECK_MACHACC, winbindd_dual_check_machine_acct, "CHECK_MACHACC" },
+ { WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" },
+ { WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" },
+#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */
+ { WINBINDD_DUAL_SIDS2XIDS, winbindd_dual_sids2xids, "DUAL_SIDS2XIDS" },
+#endif /* end DISABLED */
+ { WINBINDD_DUAL_UID2SID, winbindd_dual_uid2sid, "DUAL_UID2SID" },
+ { WINBINDD_DUAL_GID2SID, winbindd_dual_gid2sid, "DUAL_GID2SID" },
+ { WINBINDD_DUAL_UID2NAME, winbindd_dual_uid2name, "DUAL_UID2NAME" },
+ { WINBINDD_DUAL_NAME2UID, winbindd_dual_name2uid, "DUAL_NAME2UID" },
+ { WINBINDD_DUAL_GID2NAME, winbindd_dual_gid2name, "DUAL_GID2NAME" },
+ { WINBINDD_DUAL_NAME2GID, winbindd_dual_name2gid, "DUAL_NAME2GID" },
+ { WINBINDD_DUAL_SET_MAPPING, winbindd_dual_set_mapping, "DUAL_SET_MAPPING" },
+ { WINBINDD_DUAL_SET_HWM, winbindd_dual_set_hwm, "DUAL_SET_HWMS" },
+ { WINBINDD_DUAL_DUMP_MAPS, winbindd_dual_dump_maps, "DUAL_DUMP_MAPS" },
{ WINBINDD_DUAL_USERINFO, winbindd_dual_userinfo, "DUAL_USERINFO" },
+ { WINBINDD_ALLOCATE_UID, winbindd_dual_allocate_uid, "ALLOCATE_UID" },
+ { WINBINDD_ALLOCATE_GID, winbindd_dual_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_GETUSERDOMGROUPS, winbindd_dual_getuserdomgroups, "GETUSERDOMGROUPS" },
{ WINBINDD_DUAL_GETSIDALIASES, winbindd_dual_getsidaliases, "GETSIDALIASES" },
{ WINBINDD_CCACHE_NTLMAUTH, winbindd_dual_ccache_ntlm_auth, "CCACHE_NTLM_AUTH" },
@@ -432,11 +457,10 @@ const struct winbindd_child_dispatch_table domain_dispatch_table[] = {
{ WINBINDD_NUM_CMDS, NULL, "NONE" }
};
-static void child_process_request(struct winbindd_child *child,
+static void child_process_request(struct winbindd_domain *domain,
struct winbindd_cli_state *state)
{
- struct winbindd_domain *domain = child->domain;
- const struct winbindd_child_dispatch_table *table = child->table;
+ struct winbindd_child_dispatch_table *table;
/* Free response data - we may be interrupted and receive another
command before being able to send this data off. */
@@ -449,7 +473,7 @@ static void child_process_request(struct winbindd_child *child,
/* Process command */
- for (; table->fn; table++) {
+ for (table = child_dispatch_table; table->fn; table++) {
if (state->request.cmd == table->cmd) {
DEBUG(10,("process_request: request fn %s\n",
table->winbindd_cmd_name ));
@@ -459,7 +483,7 @@ static void child_process_request(struct winbindd_child *child,
}
if (!table->fn) {
- DEBUG(1 ,("child_process_request: unknown request fn number %d\n",
+ DEBUG(10,("process_request: unknown request fn number %d\n",
(int)state->request.cmd ));
state->response.result = WINBINDD_ERROR;
}
@@ -467,7 +491,6 @@ static void child_process_request(struct winbindd_child *child,
void setup_domain_child(struct winbindd_domain *domain,
struct winbindd_child *child,
- const struct winbindd_child_dispatch_table *table,
const char *explicit_logfile)
{
if (explicit_logfile != NULL) {
@@ -482,7 +505,6 @@ void setup_domain_child(struct winbindd_domain *domain,
}
child->domain = domain;
- child->table = table;
}
struct winbindd_child *children = NULL;
@@ -1084,7 +1106,7 @@ static BOOL fork_domain_child(struct winbindd_child *child)
ZERO_STRUCT(state.response);
state.request.null_term = '\0';
- child_process_request(child, &state);
+ child_process_request(child->domain, &state);
SAFE_FREE(state.request.extra_data.data);
diff --git a/source3/winbindd/winbindd_idmap.c b/source3/winbindd/winbindd_idmap.c
deleted file mode 100644
index e8b06104b2..0000000000
--- a/source3/winbindd/winbindd_idmap.c
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Async helpers for blocking functions
-
- Copyright (C) Volker Lendecke 2005
- Copyright (C) Gerald Carter 2006
- Copyright (C) Simo Sorce 2007
-
- The helpers always consist of three functions:
-
- * A request setup function that takes the necessary parameters together
- with a continuation function that is to be called upon completion
-
- * A private continuation function that is internal only. This is to be
- called by the lower-level functions in do_async(). Its only task is to
- properly call the continuation function named above.
-
- * A worker function that is called inside the appropriate child process.
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-static const struct winbindd_child_dispatch_table idmap_dispatch_table[];
-
-static struct winbindd_child static_idmap_child;
-
-void init_idmap_child(void)
-{
- setup_domain_child(NULL,
- &static_idmap_child,
- idmap_dispatch_table,
- "idmap");
-}
-
-struct winbindd_child *idmap_child(void)
-{
- return &static_idmap_child;
-}
-
-static void winbindd_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger idmap_set_mapping\n"));
- cont(private_data, False);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("idmap_set_mapping returned an error\n"));
- cont(private_data, False);
- return;
- }
-
- cont(private_data, True);
-}
-
-void winbindd_set_mapping_async(TALLOC_CTX *mem_ctx, const struct id_map *map,
- void (*cont)(void *private_data, BOOL success),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_SET_MAPPING;
- request.data.dual_idmapset.id = map->xid.id;
- request.data.dual_idmapset.type = map->xid.type;
- sid_to_string(request.data.dual_idmapset.sid, map->sid);
-
- do_async(mem_ctx, idmap_child(), &request, winbindd_set_mapping_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_set_mapping(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct id_map map;
- DOM_SID sid;
- NTSTATUS result;
-
- DEBUG(3, ("[%5lu]: dual_idmapset\n", (unsigned long)state->pid));
-
- if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))
- return WINBINDD_ERROR;
-
- map.sid = &sid;
- map.xid.id = state->request.data.dual_idmapset.id;
- map.xid.type = state->request.data.dual_idmapset.type;
- map.status = ID_MAPPED;
-
- result = idmap_set_mapping(&map);
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-static void winbindd_set_hwm_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ) = (void (*)(void *, BOOL))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger idmap_set_hwm\n"));
- cont(private_data, False);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("idmap_set_hwm returned an error\n"));
- cont(private_data, False);
- return;
- }
-
- cont(private_data, True);
-}
-
-void winbindd_set_hwm_async(TALLOC_CTX *mem_ctx, const struct unixid *xid,
- void (*cont)(void *private_data, BOOL success),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_SET_HWM;
- request.data.dual_idmapset.id = xid->id;
- request.data.dual_idmapset.type = xid->type;
-
- do_async(mem_ctx, idmap_child(), &request, winbindd_set_hwm_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_set_hwm(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct unixid xid;
- NTSTATUS result;
-
- DEBUG(3, ("[%5lu]: dual_set_hwm\n", (unsigned long)state->pid));
-
- xid.id = state->request.data.dual_idmapset.id;
- xid.type = state->request.data.dual_idmapset.type;
-
- switch (xid.type) {
- case ID_TYPE_UID:
- result = idmap_set_uid_hwm(&xid);
- break;
- case ID_TYPE_GID:
- result = idmap_set_gid_hwm(&xid);
- break;
- default:
- return WINBINDD_ERROR;
- }
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-static void winbindd_sids2xids_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, void *, int) =
- (void (*)(void *, BOOL, void *, int))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger sids2xids\n"));
- cont(private_data, False, NULL, 0);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("sids2xids returned an error\n"));
- cont(private_data, False, NULL, 0);
- return;
- }
-
- cont(private_data, True, response->extra_data.data, response->length - sizeof(response));
-}
-
-void winbindd_sids2xids_async(TALLOC_CTX *mem_ctx, void *sids, int size,
- void (*cont)(void *private_data, BOOL success, void *data, int len),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_SIDS2XIDS;
- request.extra_data.data = (char *)sids;
- request.extra_len = size;
- do_async(mem_ctx, idmap_child(), &request, winbindd_sids2xids_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_sids2xids(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DOM_SID *sids;
- struct unixid *xids;
- struct id_map **ids;
- NTSTATUS result;
- int num, i;
-
- DEBUG(3, ("[%5lu]: sids to unix ids\n", (unsigned long)state->pid));
-
- if (state->request.extra_len == 0) {
- DEBUG(0, ("Invalid buffer size!\n"));
- return WINBINDD_ERROR;
- }
-
- sids = (DOM_SID *)state->request.extra_data.data;
- num = state->request.extra_len / sizeof(DOM_SID);
-
- ids = TALLOC_ZERO_ARRAY(state->mem_ctx, struct id_map *, num + 1);
- if ( ! ids) {
- DEBUG(0, ("Out of memory!\n"));
- return WINBINDD_ERROR;
- }
- for (i = 0; i < num; i++) {
- ids[i] = TALLOC_P(ids, struct id_map);
- if ( ! ids[i]) {
- DEBUG(0, ("Out of memory!\n"));
- talloc_free(ids);
- return WINBINDD_ERROR;
- }
- ids[i]->sid = &sids[i];
- }
-
- result = idmap_sids_to_unixids(ids);
-
- if (NT_STATUS_IS_OK(result)) {
-
- xids = SMB_MALLOC_ARRAY(struct unixid, num);
- if ( ! xids) {
- DEBUG(0, ("Out of memory!\n"));
- talloc_free(ids);
- return WINBINDD_ERROR;
- }
-
- for (i = 0; i < num; i++) {
- if (ids[i]->status == ID_MAPPED) {
- xids[i].type = ids[i]->xid.type;
- xids[i].id = ids[i]->xid.id;
- } else {
- xids[i].type = -1;
- }
- }
-
- state->response.length = sizeof(state->response) + (sizeof(struct unixid) * num);
- state->response.extra_data.data = xids;
-
- } else {
- DEBUG (2, ("idmap_sids_to_unixids returned an error: 0x%08x\n", NT_STATUS_V(result)));
- talloc_free(ids);
- return WINBINDD_ERROR;
- }
-
- talloc_free(ids);
- return WINBINDD_OK;
-}
-
-static void winbindd_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, uid_t uid) =
- (void (*)(void *, BOOL, uid_t))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger sid2uid\n"));
- cont(private_data, False, 0);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("sid2uid returned an error\n"));
- cont(private_data, False, 0);
- return;
- }
-
- cont(private_data, True, response->data.uid);
-}
-
-void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- void (*cont)(void *private_data, BOOL success, uid_t uid),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_SID2UID;
- sid_to_string(request.data.dual_sid2id.sid, sid);
- do_async(mem_ctx, idmap_child(), &request, winbindd_sid2uid_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DOM_SID sid;
- NTSTATUS result;
-
- DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,
- state->request.data.dual_sid2id.sid));
-
- if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
- DEBUG(1, ("Could not get convert sid %s from string\n",
- state->request.data.dual_sid2id.sid));
- return WINBINDD_ERROR;
- }
-
- /* Find uid for this sid and return it, possibly ask the slow remote idmap */
-
- result = idmap_sid_to_uid(&sid, &(state->response.data.uid));
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-#if 0 /* not used */
-static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data);
-
-void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid,
- void (*cont)(void *private_data, BOOL success,
- const char *name),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_UID2NAME;
- request.data.uid = uid;
- do_async(mem_ctx, idmap_child(), &request, uid2name_recv,
- (void *)cont, private_data);
-}
-#endif /* not used */
-
-enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct passwd *pw;
-
- DEBUG(3, ("[%5lu]: uid2name %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.uid));
-
- pw = getpwuid(state->request.data.uid);
- if (pw == NULL) {
- DEBUG(5, ("User %lu not found\n",
- (unsigned long)state->request.data.uid));
- return WINBINDD_ERROR;
- }
-
- fstrcpy(state->response.data.name.name, pw->pw_name);
- return WINBINDD_OK;
-}
-
-#if 0 /* not used */
-static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, const char *name) =
- (void (*)(void *, BOOL, const char *))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger uid2name\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("uid2name returned an error\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- cont(private_data, True, response->data.name.name);
-}
-
-static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data);
-
-static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name,
- void (*cont)(void *private_data, BOOL success,
- uid_t uid),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_NAME2UID;
- fstrcpy(request.data.username, name);
- do_async(mem_ctx, idmap_child(), &request, name2uid_recv,
- (void *)cont, private_data);
-}
-#endif /* not used */
-
-enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct passwd *pw;
-
- /* Ensure null termination */
- state->request.data.username
- [sizeof(state->request.data.username)-1] = '\0';
-
- DEBUG(3, ("[%5lu]: name2uid %s\n", (unsigned long)state->pid,
- state->request.data.username));
-
- pw = getpwnam(state->request.data.username);
- if (pw == NULL) {
- return WINBINDD_ERROR;
- }
-
- state->response.data.uid = pw->pw_uid;
- return WINBINDD_OK;
-}
-
-#if 0 /* not used */
-static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, uid_t uid) =
- (void (*)(void *, BOOL, uid_t))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger name2uid\n"));
- cont(private_data, False, 0);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("name2uid returned an error\n"));
- cont(private_data, False, 0);
- return;
- }
-
- cont(private_data, True, response->data.uid);
-}
-#endif /* not used */
-
-static void winbindd_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, gid_t gid) =
- (void (*)(void *, BOOL, gid_t))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger sid2gid\n"));
- cont(private_data, False, 0);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("sid2gid returned an error\n"));
- cont(private_data, False, 0);
- return;
- }
-
- cont(private_data, True, response->data.gid);
-}
-
-void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
- void (*cont)(void *private_data, BOOL success, gid_t gid),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_SID2GID;
- sid_to_string(request.data.dual_sid2id.sid, sid);
-
- DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n",
- request.data.dual_sid2id.sid));
-
- do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DOM_SID sid;
- NTSTATUS result;
-
- DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,
- state->request.data.dual_sid2id.sid));
-
- if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {
- DEBUG(1, ("Could not get convert sid %s from string\n",
- state->request.data.dual_sid2id.sid));
- return WINBINDD_ERROR;
- }
-
- /* Find gid for this sid and return it, possibly ask the slow remote idmap */
-
- result = idmap_sid_to_gid(&sid, &state->response.data.gid);
-
- DEBUG(10, ("winbindd_dual_sid2gid: 0x%08x - %s - %u\n", NT_STATUS_V(result), sid_string_static(&sid), state->response.data.gid));
-
- return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
-}
-
-static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, const char *name) =
- (void (*)(void *, BOOL, const char *))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger gid2name\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("gid2name returned an error\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- cont(private_data, True, response->data.name.name);
-}
-
-void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid,
- void (*cont)(void *private_data, BOOL success,
- const char *name),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_GID2NAME;
- request.data.gid = gid;
- do_async(mem_ctx, idmap_child(), &request, gid2name_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct group *gr;
-
- DEBUG(3, ("[%5lu]: gid2name %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.gid));
-
- gr = getgrgid(state->request.data.gid);
- if (gr == NULL)
- return WINBINDD_ERROR;
-
- fstrcpy(state->response.data.name.name, gr->gr_name);
- return WINBINDD_OK;
-}
-
-#if 0 /* not used */
-static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data);
-
-static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name,
- void (*cont)(void *private_data, BOOL success,
- gid_t gid),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_NAME2GID;
- fstrcpy(request.data.groupname, name);
- do_async(mem_ctx, idmap_child(), &request, name2gid_recv,
- (void *)cont, private_data);
-}
-#endif /* not used */
-
-enum winbindd_result winbindd_dual_name2gid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- struct group *gr;
-
- /* Ensure null termination */
- state->request.data.groupname
- [sizeof(state->request.data.groupname)-1] = '\0';
-
- DEBUG(3, ("[%5lu]: name2gid %s\n", (unsigned long)state->pid,
- state->request.data.groupname));
-
- gr = getgrnam(state->request.data.groupname);
- if (gr == NULL) {
- return WINBINDD_ERROR;
- }
-
- state->response.data.gid = gr->gr_gid;
- return WINBINDD_OK;
-}
-
-#if 0 /* not used */
-static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, gid_t gid) =
- (void (*)(void *, BOOL, gid_t))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger name2gid\n"));
- cont(private_data, False, 0);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("name2gid returned an error\n"));
- cont(private_data, False, 0);
- return;
- }
-
- cont(private_data, True, response->data.gid);
-}
-#endif /* not used */
-
-/* The following uid2sid/gid2sid functions has been contributed by
- * Keith Reynolds <Keith.Reynolds@centrify.com> */
-
-static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, const char *sid) =
- (void (*)(void *, BOOL, const char *))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger uid2sid\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("uid2sid returned an error\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- cont(private_data, True, response->data.sid.sid);
-}
-
-void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
- void (*cont)(void *private_data, BOOL success, const char *sid),
- void *private_data)
-{
- struct winbindd_request request;
-
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_UID2SID;
- request.data.uid = uid;
- do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DOM_SID sid;
- NTSTATUS result;
-
- DEBUG(3,("[%5lu]: uid to sid %lu\n",
- (unsigned long)state->pid,
- (unsigned long) state->request.data.uid));
-
- /* Find sid for this uid and return it, possibly ask the slow remote idmap */
- result = idmap_uid_to_sid(&sid, state->request.data.uid);
-
- if (NT_STATUS_IS_OK(result)) {
- sid_to_string(state->response.data.sid.sid, &sid);
- state->response.data.sid.type = SID_NAME_USER;
- return WINBINDD_OK;
- }
-
- return WINBINDD_ERROR;
-}
-
-static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ, const char *sid) =
- (void (*)(void *, BOOL, const char *))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger gid2sid\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("gid2sid returned an error\n"));
- cont(private_data, False, NULL);
- return;
- }
-
- cont(private_data, True, response->data.sid.sid);
-}
-
-void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
- void (*cont)(void *private_data, BOOL success, const char *sid),
- void *private_data)
-{
- struct winbindd_request request;
-
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_GID2SID;
- request.data.gid = gid;
- do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DOM_SID sid;
- NTSTATUS result;
-
- DEBUG(3,("[%5lu]: gid %lu to sid\n",
- (unsigned long)state->pid,
- (unsigned long) state->request.data.gid));
-
- /* Find sid for this gid and return it, possibly ask the slow remote idmap */
- result = idmap_gid_to_sid(&sid, state->request.data.gid);
-
- if (NT_STATUS_IS_OK(result)) {
- sid_to_string(state->response.data.sid.sid, &sid);
- DEBUG(10, ("[%5lu]: retrieved sid: %s\n",
- (unsigned long)state->pid,
- state->response.data.sid.sid));
- state->response.data.sid.type = SID_NAME_DOM_GRP;
- return WINBINDD_OK;
- }
-
- return WINBINDD_ERROR;
-}
-
-static void winbindd_dump_id_maps_recv(TALLOC_CTX *mem_ctx, BOOL success,
- struct winbindd_response *response,
- void *c, void *private_data)
-{
- void (*cont)(void *priv, BOOL succ) =
- (void (*)(void *, BOOL))c;
-
- if (!success) {
- DEBUG(5, ("Could not trigger a map dump\n"));
- cont(private_data, False);
- return;
- }
-
- if (response->result != WINBINDD_OK) {
- DEBUG(5, ("idmap dump maps returned an error\n"));
- cont(private_data, False);
- return;
- }
-
- cont(private_data, True);
-}
-
-void winbindd_dump_maps_async(TALLOC_CTX *mem_ctx, void *data, int size,
- void (*cont)(void *private_data, BOOL success),
- void *private_data)
-{
- struct winbindd_request request;
- ZERO_STRUCT(request);
- request.cmd = WINBINDD_DUAL_DUMP_MAPS;
- request.extra_data.data = (char *)data;
- request.extra_len = size;
- do_async(mem_ctx, idmap_child(), &request, winbindd_dump_id_maps_recv,
- (void *)cont, private_data);
-}
-
-enum winbindd_result winbindd_dual_dump_maps(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- DEBUG(3, ("[%5lu]: dual dump maps\n", (unsigned long)state->pid));
-
- idmap_dump_maps((char *)state->request.extra_data.data);
-
- return WINBINDD_OK;
-}
-
-static const struct winbindd_child_dispatch_table idmap_dispatch_table[] = {
-
- { WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" },
- { WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" },
-#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */
- { WINBINDD_DUAL_SIDS2XIDS, winbindd_dual_sids2xids, "DUAL_SIDS2XIDS" },
-#endif /* end DISABLED */
- { WINBINDD_DUAL_UID2SID, winbindd_dual_uid2sid, "DUAL_UID2SID" },
- { WINBINDD_DUAL_GID2SID, winbindd_dual_gid2sid, "DUAL_GID2SID" },
- { WINBINDD_DUAL_UID2NAME, winbindd_dual_uid2name, "DUAL_UID2NAME" },
- { WINBINDD_DUAL_NAME2UID, winbindd_dual_name2uid, "DUAL_NAME2UID" },
- { WINBINDD_DUAL_GID2NAME, winbindd_dual_gid2name, "DUAL_GID2NAME" },
- { WINBINDD_DUAL_NAME2GID, winbindd_dual_name2gid, "DUAL_NAME2GID" },
- { WINBINDD_DUAL_SET_MAPPING, winbindd_dual_set_mapping, "DUAL_SET_MAPPING" },
- { WINBINDD_DUAL_SET_HWM, winbindd_dual_set_hwm, "DUAL_SET_HWMS" },
- { WINBINDD_DUAL_DUMP_MAPS, winbindd_dual_dump_maps, "DUAL_DUMP_MAPS" },
- { WINBINDD_ALLOCATE_UID, winbindd_dual_allocate_uid, "ALLOCATE_UID" },
- { WINBINDD_ALLOCATE_GID, winbindd_dual_allocate_gid, "ALLOCATE_GID" },
- /* End of list */
-
- { WINBINDD_NUM_CMDS, NULL, "NONE" }
-};
diff --git a/source3/winbindd/winbindd_locator.c b/source3/winbindd/winbindd_locator.c
deleted file mode 100644
index ade2c1539b..0000000000
--- a/source3/winbindd/winbindd_locator.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind daemon - miscellaneous other functions
-
- Copyright (C) Tim Potter 2000
- Copyright (C) Andrew Bartlett 2002
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-
-static const struct winbindd_child_dispatch_table locator_dispatch_table[];
-
-static struct winbindd_child static_locator_child;
-
-void init_locator_child(void)
-{
- setup_domain_child(NULL,
- &static_locator_child,
- locator_dispatch_table,
- "locator");
-}
-
-struct winbindd_child *locator_child(void)
-{
- return &static_locator_child;
-}
-
-void winbindd_dsgetdcname(struct winbindd_cli_state *state)
-{
- state->request.domain_name
- [sizeof(state->request.domain_name)-1] = '\0';
-
- DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid,
- state->request.domain_name));
-
- sendto_child(state, locator_child());
-}
-
-static enum winbindd_result dual_dsgetdcname(struct winbindd_domain *domain,
- struct winbindd_cli_state *state)
-{
- NTSTATUS result;
- struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
- const char *dc = NULL;
-
- state->request.domain_name
- [sizeof(state->request.domain_name)-1] = '\0';
-
- DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid,
- state->request.domain_name));
-
- result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name,
- NULL, NULL, state->request.flags, &info);
-
- if (!NT_STATUS_IS_OK(result)) {
- return WINBINDD_ERROR;
- }
-
- if (info->domain_controller_address) {
- dc = info->domain_controller_address;
- if ((dc[0] == '\\') && (dc[1] == '\\')) {
- dc += 2;
- }
- }
-
- if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) {
- dc = info->domain_controller_name;
- }
-
- if (!dc || !*dc) {
- return WINBINDD_ERROR;
- }
-
- fstrcpy(state->response.data.dc_name, dc);
-
- return WINBINDD_OK;
-}
-
-static const struct winbindd_child_dispatch_table locator_dispatch_table[] = {
- { WINBINDD_DSGETDCNAME, dual_dsgetdcname, "DSGETDCNAME" },
-
- { WINBINDD_NUM_CMDS, NULL, "NONE" }
-};
diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c
index 987926e398..5513e1790b 100644
--- a/source3/winbindd/winbindd_misc.c
+++ b/source3/winbindd/winbindd_misc.c
@@ -289,6 +289,70 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
return WINBINDD_OK;
}
+static struct winbindd_child static_locator_child;
+
+void init_locator_child(void)
+{
+ setup_domain_child(NULL, &static_locator_child, "locator");
+}
+
+struct winbindd_child *locator_child(void)
+{
+ return &static_locator_child;
+}
+
+void winbindd_dsgetdcname(struct winbindd_cli_state *state)
+{
+ state->request.domain_name
+ [sizeof(state->request.domain_name)-1] = '\0';
+
+ DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid,
+ state->request.domain_name));
+
+ sendto_child(state, locator_child());
+}
+
+enum winbindd_result winbindd_dual_dsgetdcname(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ NTSTATUS result;
+ struct DS_DOMAIN_CONTROLLER_INFO *info = NULL;
+ const char *dc = NULL;
+
+ state->request.domain_name
+ [sizeof(state->request.domain_name)-1] = '\0';
+
+ DEBUG(3, ("[%5lu]: DsGetDcName for %s\n", (unsigned long)state->pid,
+ state->request.domain_name));
+
+ result = DsGetDcName(state->mem_ctx, NULL, state->request.domain_name,
+ NULL, NULL, state->request.flags, &info);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ return WINBINDD_ERROR;
+ }
+
+ if (info->domain_controller_address) {
+ dc = info->domain_controller_address;
+ if ((dc[0] == '\\') && (dc[1] == '\\')) {
+ dc += 2;
+ }
+ }
+
+ if ((!dc || !is_ipaddress(dc)) && info->domain_controller_name) {
+ dc = info->domain_controller_name;
+ }
+
+ if (!dc || !*dc) {
+ return WINBINDD_ERROR;
+ }
+
+ fstrcpy(state->response.data.dc_name, dc);
+
+ return WINBINDD_OK;
+}
+
+
struct sequence_state {
TALLOC_CTX *mem_ctx;
struct winbindd_cli_state *cli_state;
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index f823e1d7b2..78128521c4 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1261,17 +1261,6 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
/* check authentication loop */
do {
- NTSTATUS (*logon_fn)(struct rpc_pipe_client
- *cli, TALLOC_CTX *mem_ctx,
- uint32 logon_parameters,
- const char *server,
- const char *username,
- const char *domain,
- const char *workstation,
- const uint8 chal[8],
- DATA_BLOB lm_response,
- DATA_BLOB nt_response,
- NET_USER_INFO_3 *info3);
ZERO_STRUCTP(my_info3);
retry = False;
@@ -1283,11 +1272,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
goto done;
}
- logon_fn = contact_domain->can_do_samlogon_ex
- ? rpccli_netlogon_sam_network_logon_ex
- : rpccli_netlogon_sam_network_logon;
-
- result = logon_fn(netlogon_pipe,
+ result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
state->mem_ctx,
0,
contact_domain->dcname, /* server name */
@@ -1298,16 +1283,6 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain,
lm_resp,
nt_resp,
my_info3);
-
- if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
- && contact_domain->can_do_samlogon_ex) {
- DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
- "retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = False;
- retry = True;
- continue;
- }
-
attempts += 1;
/* We have to try a second time as cm_connect_netlogon
@@ -1803,18 +1778,6 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
}
do {
- NTSTATUS (*logon_fn)(struct rpc_pipe_client
- *cli, TALLOC_CTX *mem_ctx,
- uint32 logon_parameters,
- const char *server,
- const char *username,
- const char *domain,
- const char *workstation,
- const uint8 chal[8],
- DATA_BLOB lm_response,
- DATA_BLOB nt_response,
- NET_USER_INFO_3 *info3);
-
ZERO_STRUCT(info3);
retry = False;
@@ -1827,32 +1790,19 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
goto done;
}
- logon_fn = contact_domain->can_do_samlogon_ex
- ? rpccli_netlogon_sam_network_logon_ex
- : rpccli_netlogon_sam_network_logon;
-
- result = logon_fn(netlogon_pipe,
- state->mem_ctx,
- state->request.data.auth_crap.logon_parameters,
- contact_domain->dcname,
- name_user,
- name_domain,
- /* Bug #3248 - found by Stefan Burkei. */
- workstation, /* We carefully set this above so use it... */
- state->request.data.auth_crap.chal,
- lm_resp,
- nt_resp,
- &info3);
-
- if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
- && contact_domain->can_do_samlogon_ex) {
- DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
- "retrying with NetSamLogon\n"));
- contact_domain->can_do_samlogon_ex = False;
- retry = True;
- continue;
- }
-
+ result = rpccli_netlogon_sam_network_logon(netlogon_pipe,
+ state->mem_ctx,
+ state->request.data.auth_crap.logon_parameters,
+ contact_domain->dcname,
+ name_user,
+ name_domain,
+ /* Bug #3248 - found by Stefan Burkei. */
+ workstation, /* We carefully set this above so use it... */
+ state->request.data.auth_crap.chal,
+ lm_resp,
+ nt_resp,
+ &info3);
+
attempts += 1;
/* We have to try a second time as cm_connect_netlogon
diff --git a/source3/winbindd/winbindd_sid.c b/source3/winbindd/winbindd_sid.c
index b607db2b19..48e84d35e5 100644
--- a/source3/winbindd/winbindd_sid.c
+++ b/source3/winbindd/winbindd_sid.c
@@ -152,6 +152,18 @@ void winbindd_lookuprids(struct winbindd_cli_state *state)
sendto_domain(state, domain);
}
+static struct winbindd_child static_idmap_child;
+
+void init_idmap_child(void)
+{
+ setup_domain_child(NULL, &static_idmap_child, "idmap");
+}
+
+struct winbindd_child *idmap_child(void)
+{
+ return &static_idmap_child;
+}
+
/* Convert a sid to a uid. We assume we only have one rid attached to the
sid. */
diff --git a/source3/winbindd/winbindd_sockinit.c b/source3/winbindd/winbindd_sockinit.c
deleted file mode 100644
index 886b67fb47..0000000000
--- a/source3/winbindd/winbindd_sockinit.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Copyright (C) Tim Potter 2000-2001
- Copyright (C) 2001 by Martin Pool <mbp@samba.org>
- Copyright (C) James Peach 2007
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "winbindd.h"
-#include "smb_launchd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-/* Open the winbindd socket */
-
-static int _winbindd_socket = -1;
-static int _winbindd_priv_socket = -1;
-static BOOL unlink_winbindd_socket = True;
-
-static int open_winbindd_socket(void)
-{
- if (_winbindd_socket == -1) {
- _winbindd_socket = create_pipe_sock(
- get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
- DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
- _winbindd_socket));
- }
-
- return _winbindd_socket;
-}
-
-static int open_winbindd_priv_socket(void)
-{
- if (_winbindd_priv_socket == -1) {
- _winbindd_priv_socket = create_pipe_sock(
- get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
- DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
- _winbindd_priv_socket));
- }
-
- return _winbindd_priv_socket;
-}
-
-/* Close the winbindd socket */
-
-static void close_winbindd_socket(void)
-{
- if (_winbindd_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_socket));
- close(_winbindd_socket);
- _winbindd_socket = -1;
- }
- if (_winbindd_priv_socket != -1) {
- DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
- _winbindd_priv_socket));
- close(_winbindd_priv_socket);
- _winbindd_priv_socket = -1;
- }
-}
-
-BOOL winbindd_init_sockets(int *public_sock, int *priv_sock,
- int *idle_timeout_sec)
-{
- struct smb_launch_info linfo;
-
- if (smb_launchd_checkin_names(&linfo, "WinbindPublicPipe",
- "WinbindPrivilegedPipe", NULL)) {
- if (linfo.num_sockets != 2) {
- DEBUG(0, ("invalid launchd configuration, "
- "expected 2 sockets but got %d\n",
- linfo.num_sockets));
- return False;
- }
-
- *public_sock = _winbindd_socket = linfo.socket_list[0];
- *priv_sock = _winbindd_priv_socket = linfo.socket_list[1];
- *idle_timeout_sec = linfo.idle_timeout_secs;
-
- unlink_winbindd_socket = False;
-
- smb_launchd_checkout(&linfo);
- return True;
- } else {
- *public_sock = open_winbindd_socket();
- *priv_sock = open_winbindd_priv_socket();
- *idle_timeout_sec = -1;
-
- if (*public_sock == -1 || *priv_sock == -1) {
- DEBUG(0, ("failed to open winbindd pipes: %s\n",
- errno ? strerror(errno) : "unknown error"));
- return False;
- }
-
- return True;
- }
-}
-
-void winbindd_release_sockets(void)
-{
- pstring path;
-
- close_winbindd_socket();
-
- /* Remove socket file */
- if (unlink_winbindd_socket) {
- pstr_sprintf(path, "%s/%s",
- get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME);
- unlink(path);
- }
-}
-
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 49d20c527e..c2fe09eead 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -35,6 +35,7 @@ extern struct winbindd_methods passdb_methods;
* Winbind daemon for NT domain authentication nss module.
**/
+
/* The list of trusted domains. Note that the list can be deleted and
recreated using the init_domain_list() function so pointers to
individual winbindd_domain structures cannot be made. Keep a copy of
@@ -324,10 +325,7 @@ static void trustdom_recv(void *private_data, BOOL success)
&cache_methods,
&sid);
if (domain) {
- setup_domain_child(domain,
- &domain->child,
- domain_dispatch_table,
- NULL);
+ setup_domain_child(domain, &domain->child, NULL);
}
}
p=q;
@@ -696,10 +694,7 @@ BOOL init_domain_list(void)
domain = add_trusted_domain("BUILTIN", NULL, &passdb_methods,
&global_sid_Builtin);
if (domain) {
- setup_domain_child(domain,
- &domain->child,
- domain_dispatch_table,
- NULL);
+ setup_domain_child(domain, &domain->child, NULL);
}
/* Local SAM */
@@ -710,10 +705,7 @@ BOOL init_domain_list(void)
if ( role != ROLE_DOMAIN_MEMBER ) {
domain->primary = True;
}
- setup_domain_child(domain,
- &domain->child,
- domain_dispatch_table,
- NULL);
+ setup_domain_child(domain, &domain->child, NULL);
}
/* Add ourselves as the first entry. */
@@ -730,11 +722,8 @@ BOOL init_domain_list(void)
&cache_methods, &our_sid);
if (domain) {
domain->primary = True;
- setup_domain_child(domain,
- &domain->child,
- domain_dispatch_table,
- NULL);
-
+ setup_domain_child(domain, &domain->child, NULL);
+
/* Even in the parent winbindd we'll need to
talk to the DC, so try and see if we can
contact it. Theoretically this isn't neccessary
@@ -779,10 +768,7 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid )
domain->internal = False;
domain->online = True;
- setup_domain_child(domain,
- &domain->child,
- domain_dispatch_table,
- NULL);
+ setup_domain_child(domain, &domain->child, NULL);
wcache_tdc_add_domain( domain );
@@ -1179,6 +1165,53 @@ char *get_winbind_priv_pipe_dir(void)
return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);
}
+/* Open the winbindd socket */
+
+static int _winbindd_socket = -1;
+static int _winbindd_priv_socket = -1;
+
+int open_winbindd_socket(void)
+{
+ if (_winbindd_socket == -1) {
+ _winbindd_socket = create_pipe_sock(
+ get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
+ DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",
+ _winbindd_socket));
+ }
+
+ return _winbindd_socket;
+}
+
+int open_winbindd_priv_socket(void)
+{
+ if (_winbindd_priv_socket == -1) {
+ _winbindd_priv_socket = create_pipe_sock(
+ get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
+ DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",
+ _winbindd_priv_socket));
+ }
+
+ return _winbindd_priv_socket;
+}
+
+/* Close the winbindd socket */
+
+void close_winbindd_socket(void)
+{
+ if (_winbindd_socket != -1) {
+ DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
+ _winbindd_socket));
+ close(_winbindd_socket);
+ _winbindd_socket = -1;
+ }
+ if (_winbindd_priv_socket != -1) {
+ DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",
+ _winbindd_priv_socket));
+ close(_winbindd_priv_socket);
+ _winbindd_priv_socket = -1;
+ }
+}
+
/*
* Client list accessor functions
*/