diff options
author | Simo Sorce <idra@samba.org> | 2008-08-26 18:56:49 -0400 |
---|---|---|
committer | Simo Sorce <idra@samba.org> | 2008-08-26 18:56:49 -0400 |
commit | a1de4e988d7780f687bb7ed2288faf3dfbb9da71 (patch) | |
tree | abc569f52f33efdf48135faf7f0c790601eef229 /source3/winbindd | |
parent | 5e7655fa27f7b2c9c54edfc25f86974dbdb23ea4 (diff) | |
parent | 95cc5ee395ab9d7f6f79d341ad20bc486c292a8d (diff) | |
download | samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.tar.gz samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.tar.bz2 samba-a1de4e988d7780f687bb7ed2288faf3dfbb9da71.zip |
Merge branch 'v3-devel' of ssh://git.samba.org/data/git/samba into v3-devel
(This used to be commit e038f1cf9fb305fc1e7a4189208e451d30aaa1f0)
Diffstat (limited to 'source3/winbindd')
-rw-r--r-- | source3/winbindd/idmap_cache.c | 261 | ||||
-rw-r--r-- | source3/winbindd/idmap_util.c | 2 | ||||
-rw-r--r-- | source3/winbindd/winbindd.h | 2 | ||||
-rw-r--r-- | source3/winbindd/winbindd_cm.c | 103 | ||||
-rw-r--r-- | source3/winbindd/winbindd_dual.c | 120 | ||||
-rw-r--r-- | source3/winbindd/winbindd_misc.c | 5 | ||||
-rw-r--r-- | source3/winbindd/winbindd_pam.c | 444 | ||||
-rw-r--r-- | source3/winbindd/winbindd_proto.h | 1 | ||||
-rw-r--r-- | source3/winbindd/winbindd_util.c | 14 |
9 files changed, 409 insertions, 543 deletions
diff --git a/source3/winbindd/idmap_cache.c b/source3/winbindd/idmap_cache.c deleted file mode 100644 index 496f70ab45..0000000000 --- a/source3/winbindd/idmap_cache.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - Unix SMB/CIFS implementation. - ID Mapping Cache - - Copyright (C) Volker Lendecke 2008 - - 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" - -/** - * Find a sid2uid mapping - * @param[in] sid the sid to map - * @param[out] puid where to put the result - * @param[out] expired is the cache entry expired? - * @retval Was anything in the cache at all? - * - * If *puid == -1 this was a negative mapping. - */ - -bool idmap_cache_find_sid2uid(const struct dom_sid *sid, uid_t *puid, - bool *expired) -{ - fstring sidstr; - char *key; - char *value; - char *endptr; - time_t timeout; - uid_t uid; - bool ret; - - key = talloc_asprintf(talloc_tos(), "IDMAP/SID2UID/%s", - sid_to_fstring(sidstr, sid)); - if (key == NULL) { - return false; - } - ret = gencache_get(key, &value, &timeout); - TALLOC_FREE(key); - if (!ret) { - return false; - } - uid = strtol(value, &endptr, 10); - ret = (*endptr == '\0'); - SAFE_FREE(value); - if (ret) { - *puid = uid; - *expired = (timeout <= time(NULL)); - } - return ret; -} - -/** - * Find a uid2sid mapping - * @param[in] uid the uid to map - * @param[out] sid where to put the result - * @param[out] expired is the cache entry expired? - * @retval Was anything in the cache at all? - * - * If "is_null_sid(sid)", this was a negative mapping. - */ - -bool idmap_cache_find_uid2sid(uid_t uid, struct dom_sid *sid, bool *expired) -{ - char *key; - char *value; - time_t timeout; - bool ret = true; - - key = talloc_asprintf(talloc_tos(), "IDMAP/UID2SID/%d", (int)uid); - if (key == NULL) { - return false; - } - ret = gencache_get(key, &value, &timeout); - TALLOC_FREE(key); - if (!ret) { - return false; - } - ZERO_STRUCTP(sid); - if (value[0] != '-') { - ret = string_to_sid(sid, value); - } - SAFE_FREE(value); - if (ret) { - *expired = (timeout <= time(NULL)); - } - return ret; -} - -/** - * Store a mapping in the idmap cache - * @param[in] sid the sid to map - * @param[in] uid the uid to map - * - * If both parameters are valid values, then a positive mapping in both - * directions is stored. If "is_null_sid(sid)" is true, then this will be a - * negative mapping of uid, we want to cache that for this uid we could not - * find anything. Likewise if "uid==-1", then we want to cache that we did not - * find a mapping for the sid passed here. - */ - -void idmap_cache_set_sid2uid(const struct dom_sid *sid, uid_t uid) -{ - time_t now = time(NULL); - time_t timeout; - fstring sidstr, key, value; - - if (!is_null_sid(sid)) { - fstr_sprintf(key, "IDMAP/SID2UID/%s", - sid_to_fstring(sidstr, sid)); - fstr_sprintf(value, "%d", (int)uid); - timeout = (uid == -1) - ? lp_idmap_negative_cache_time() - : lp_idmap_cache_time(); - gencache_set(key, value, now + timeout); - } - if (uid != -1) { - fstr_sprintf(key, "IDMAP/UID2SID/%d", (int)uid); - if (is_null_sid(sid)) { - /* negative uid mapping */ - fstrcpy(value, "-"); - timeout = lp_idmap_negative_cache_time(); - } - else { - sid_to_fstring(value, sid); - timeout = lp_idmap_cache_time(); - } - gencache_set(key, value, now + timeout); - } -} - -/** - * Find a sid2gid mapping - * @param[in] sid the sid to map - * @param[out] pgid where to put the result - * @param[out] expired is the cache entry expired? - * @retval Was anything in the cache at all? - * - * If *pgid == -1 this was a negative mapping. - */ - -bool idmap_cache_find_sid2gid(const struct dom_sid *sid, gid_t *pgid, - bool *expired) -{ - fstring sidstr; - char *key; - char *value; - char *endptr; - time_t timeout; - gid_t gid; - bool ret; - - key = talloc_asprintf(talloc_tos(), "IDMAP/SID2GID/%s", - sid_to_fstring(sidstr, sid)); - if (key == NULL) { - return false; - } - ret = gencache_get(key, &value, &timeout); - TALLOC_FREE(key); - if (!ret) { - return false; - } - gid = strtol(value, &endptr, 10); - ret = (*endptr == '\0'); - SAFE_FREE(value); - if (ret) { - *pgid = gid; - *expired = (timeout <= time(NULL)); - } - return ret; -} - -/** - * Find a gid2sid mapping - * @param[in] gid the gid to map - * @param[out] sid where to put the result - * @param[out] expired is the cache entry expired? - * @retval Was anything in the cache at all? - * - * If "is_null_sid(sid)", this was a negative mapping. - */ - -bool idmap_cache_find_gid2sid(gid_t gid, struct dom_sid *sid, bool *expired) -{ - char *key; - char *value; - time_t timeout; - bool ret = true; - - key = talloc_asprintf(talloc_tos(), "IDMAP/GID2SID/%d", (int)gid); - if (key == NULL) { - return false; - } - ret = gencache_get(key, &value, &timeout); - TALLOC_FREE(key); - if (!ret) { - return false; - } - ZERO_STRUCTP(sid); - if (value[0] != '-') { - ret = string_to_sid(sid, value); - } - SAFE_FREE(value); - if (ret) { - *expired = (timeout <= time(NULL)); - } - return ret; -} - -/** - * Store a mapping in the idmap cache - * @param[in] sid the sid to map - * @param[in] gid the gid to map - * - * If both parameters are valid values, then a positive mapping in both - * directions is stored. If "is_null_sid(sid)" is true, then this will be a - * negative mapping of gid, we want to cache that for this gid we could not - * find anything. Likewise if "gid==-1", then we want to cache that we did not - * find a mapping for the sid passed here. - */ - -void idmap_cache_set_sid2gid(const struct dom_sid *sid, gid_t gid) -{ - time_t now = time(NULL); - time_t timeout; - fstring sidstr, key, value; - - if (!is_null_sid(sid)) { - fstr_sprintf(key, "IDMAP/SID2GID/%s", - sid_to_fstring(sidstr, sid)); - fstr_sprintf(value, "%d", (int)gid); - timeout = (gid == -1) - ? lp_idmap_negative_cache_time() - : lp_idmap_cache_time(); - gencache_set(key, value, now + timeout); - } - if (gid != -1) { - fstr_sprintf(key, "IDMAP/GID2SID/%d", (int)gid); - if (is_null_sid(sid)) { - /* negative gid mapping */ - fstrcpy(value, "-"); - timeout = lp_idmap_negative_cache_time(); - } - else { - sid_to_fstring(value, sid); - timeout = lp_idmap_cache_time(); - } - gencache_set(key, value, now + timeout); - } -} diff --git a/source3/winbindd/idmap_util.c b/source3/winbindd/idmap_util.c index 2a6beca5a2..b10a1a4ba9 100644 --- a/source3/winbindd/idmap_util.c +++ b/source3/winbindd/idmap_util.c @@ -87,7 +87,7 @@ NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid) DEBUG(10,("gid = [%lu]\n", (unsigned long)gid)); - if (idmap_cache_find_uid2sid(gid, sid, &expired)) { + if (idmap_cache_find_gid2sid(gid, sid, &expired)) { DEBUG(10, ("idmap_cache_find_gid2sid found %d%s\n", gid, expired ? " (expired)": "")); if (expired && idmap_is_online()) { diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index fe0c076209..04b0b39f81 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -153,6 +153,7 @@ struct winbindd_child { struct fd_event event; struct timed_event *lockout_policy_event; + struct timed_event *machine_password_change_event; struct winbindd_async_request *requests; const struct winbindd_child_dispatch_table *table; @@ -204,6 +205,7 @@ struct winbindd_domain { uint32_t id_range_low, id_range_high; /* A working DC */ + pid_t dc_probe_pid; /* Child we're using to detect the DC. */ fstring dcname; struct sockaddr_storage dcaddr; diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 47df4e4058..71f1a56519 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -8,17 +8,17 @@ Copyright (C) Gerald (Jerry) Carter 2003-2005. Copyright (C) Volker Lendecke 2004-2005 Copyright (C) Jeremy Allison 2006 - + 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/>. */ @@ -27,14 +27,14 @@ 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 - + 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 @@ -171,20 +171,33 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) struct dc_name_ip *dcs = NULL; int num_dcs = 0; TALLOC_CTX *mem_ctx = NULL; - pid_t child_pid; pid_t parent_pid = sys_getpid(); /* Stop zombies */ CatchChild(); - child_pid = sys_fork(); + if (domain->dc_probe_pid != (pid_t)-1) { + /* + * We might already have a DC probe + * child working, check. + */ + if (process_exists_by_pid(domain->dc_probe_pid)) { + DEBUG(10,("fork_child_dc_connect: pid %u already " + "checking for DC's.\n", + (unsigned int)domain->dc_probe_pid)); + return true; + } + domain->dc_probe_pid = (pid_t)-1; + } + + domain->dc_probe_pid = sys_fork(); - if (child_pid == -1) { + if (domain->dc_probe_pid == (pid_t)-1) { DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno))); return False; } - if (child_pid != 0) { + if (domain->dc_probe_pid != (pid_t)0) { /* Parent */ messaging_register(winbind_messaging_context(), NULL, MSG_WINBIND_TRY_TO_GO_ONLINE, @@ -201,6 +214,11 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) if (!reinit_after_fork(winbind_messaging_context(), true)) { DEBUG(0,("reinit_after_fork() failed\n")); + messaging_send_buf(winbind_messaging_context(), + pid_to_procid(parent_pid), + MSG_WINBIND_FAILED_TO_GO_ONLINE, + (uint8 *)domain->name, + strlen(domain->name)+1); _exit(0); } @@ -218,6 +236,11 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) mem_ctx = talloc_init("fork_child_dc_connect"); if (!mem_ctx) { DEBUG(0,("talloc_init failed.\n")); + messaging_send_buf(winbind_messaging_context(), + pid_to_procid(parent_pid), + MSG_WINBIND_FAILED_TO_GO_ONLINE, + (uint8 *)domain->name, + strlen(domain->name)+1); _exit(0); } @@ -291,12 +314,12 @@ static void check_domain_online_handler(struct event_context *ctx, static void calc_new_online_timeout_check(struct winbindd_domain *domain) { - int wbc = lp_winbind_cache_time(); + int wbr = lp_winbind_reconnect_delay(); if (domain->startup) { domain->check_online_timeout = 10; - } else if (domain->check_online_timeout < wbc) { - domain->check_online_timeout = wbc; + } else if (domain->check_online_timeout < wbr) { + domain->check_online_timeout = wbr; } } @@ -336,7 +359,7 @@ void set_domain_offline(struct winbindd_domain *domain) } /* If we're in statup mode, check again in 10 seconds, not in - lp_winbind_cache_time() seconds (which is 5 mins by default). */ + lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */ calc_new_online_timeout_check(domain); @@ -360,7 +383,7 @@ void set_domain_offline(struct winbindd_domain *domain) if ( domain->primary ) { struct winbindd_child *idmap = idmap_child(); - + if ( idmap->pid != 0 ) { messaging_send_buf(winbind_messaging_context(), pid_to_procid(idmap->pid), @@ -439,7 +462,7 @@ static void set_domain_online(struct winbindd_domain *domain) if ( domain->primary ) { struct winbindd_child *idmap = idmap_child(); - + if ( idmap->pid != 0 ) { messaging_send_buf(winbind_messaging_context(), pid_to_procid(idmap->pid), @@ -530,7 +553,7 @@ void winbind_add_failed_connection_entry(const struct winbindd_domain *domain, an authenticated connection if DCs have the RestrictAnonymous registry entry set > 0, or the "Additional restrictions for anonymous connections" set in the win2k Local Security Policy. - + Caller to free() result in domain, username, password */ @@ -539,12 +562,12 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password) *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL); *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL); *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL); - + if (*username && **username) { if (!*domain || !**domain) *domain = smb_xstrdup(lp_workgroup()); - + if (!*password || !**password) *password = smb_xstrdup(""); @@ -680,7 +703,7 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, { const char *account_name; const char *name = NULL; - + /* If we are a DC and this is not our own domain */ if (IS_DC) { @@ -690,10 +713,10 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, if (!our_domain) return NT_STATUS_INVALID_SERVER_STATE; - + name = our_domain->name; } - + if (!get_trust_pw_clear(name, machine_password, &account_name, NULL)) { @@ -715,7 +738,7 @@ static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, if (!our_domain) { return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } - + if (asprintf(machine_krb5_principal, "%s$@%s", account_name, our_domain->alt_name) == -1) { @@ -852,7 +875,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, domain->name, machine_password); + cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); goto session_setup_done; } } @@ -877,7 +900,7 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, result = ads_ntstatus(ads_status); if (NT_STATUS_IS_OK(result)) { /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ - cli_init_creds(*cli, machine_account, domain->name, machine_password); + cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); goto session_setup_done; } } @@ -914,6 +937,9 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain, anon_fallback: /* Fall back to anonymous connection, this might fail later */ + DEBUG(10,("cm_prepare_connection: falling back to anonymous " + "connection for DC %s\n", + controller )); if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0, NULL, 0, ""))) { @@ -1316,7 +1342,7 @@ static bool find_new_dc(TALLOC_CTX *mem_ctx, TALLOC_FREE(dcnames); num_dcnames = 0; - + TALLOC_FREE(addrs); num_addrs = 0; @@ -1342,7 +1368,7 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, /* we have to check the server affinity cache here since later we selecte a DC based on response time and not preference */ - + /* Check the negative connection cache before talking to it. It going down may have triggered the reconnection. */ @@ -1592,26 +1618,26 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx = NULL; DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name )); - + /* Our primary domain doesn't need to worry about trust flags. Force it to go through the network setup */ if ( domain->primary ) { return False; } - + our_domain = find_our_domain(); - + if ( !connection_ok(our_domain) ) { DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n")); return False; } /* This won't work unless our domain is AD */ - + if ( !our_domain->active_directory ) { return False; } - + /* Use DsEnumerateDomainTrusts to get us the trust direction and type */ @@ -1672,13 +1698,13 @@ static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ) if ( !winbindd_can_contact_domain( domain) ) domain->internal = True; - + break; } } - + talloc_destroy( mem_ctx ); - + return domain->initialized; } @@ -1775,7 +1801,7 @@ no_dssetup: result = rpccli_lsa_open_policy2(cli, mem_ctx, True, SEC_RIGHTS_MAXIMUM_ALLOWED, &pol); - + if (NT_STATUS_IS_OK(result)) { /* This particular query is exactly what Win2k clients use to determine that the DC is active directory */ @@ -1904,6 +1930,10 @@ static bool cm_get_schannel_dcinfo(struct winbindd_domain *domain, /* Return a pointer to the struct dcinfo from the netlogon pipe. */ + if (!domain->conn.netlogon_pipe->dc) { + return false; + } + *ppdc = domain->conn.netlogon_pipe->dc; return True; } @@ -1930,6 +1960,7 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, goto done; } + /* * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated * sign and sealed pipe using the machine account password by @@ -2303,7 +2334,7 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, if (!NT_STATUS_IS_OK(result)) { DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error " "was %s\n", nt_errstr(result))); - + /* make sure we return something besides OK */ return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE; } diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 1e8325f983..916e8c07c7 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -840,6 +840,111 @@ static void account_lockout_policy_handler(struct event_context *ctx, child); } +static time_t get_machine_password_timeout(void) +{ + /* until we have gpo support use lp setting */ + return lp_machine_password_timeout(); +} + +static bool calculate_next_machine_pwd_change(const char *domain, + struct timeval *t) +{ + time_t pass_last_set_time; + time_t timeout; + time_t next_change; + char *pw; + + pw = secrets_fetch_machine_password(domain, + &pass_last_set_time, + NULL); + + if (pw == NULL) { + DEBUG(0,("cannot fetch own machine password ????")); + return false; + } + + SAFE_FREE(pw); + + timeout = get_machine_password_timeout(); + if (timeout == 0) { + DEBUG(10,("machine password never expires\n")); + return false; + } + + if (time(NULL) < (pass_last_set_time + timeout)) { + next_change = pass_last_set_time + timeout; + DEBUG(10,("machine password still valid until: %s\n", + http_timestring(next_change))); + *t = timeval_set(next_change, 0); + return true; + } + + DEBUG(10,("machine password expired, needs immediate change\n")); + + *t = timeval_zero(); + + return true; +} + +static void machine_password_change_handler(struct event_context *ctx, + struct timed_event *te, + const struct timeval *now, + void *private_data) +{ + struct winbindd_child *child = + (struct winbindd_child *)private_data; + struct rpc_pipe_client *netlogon_pipe = NULL; + TALLOC_CTX *frame; + NTSTATUS result; + struct timeval next_change; + + DEBUG(10,("machine_password_change_handler called\n")); + + TALLOC_FREE(child->machine_password_change_event); + + if (!calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + return; + } + + if (!winbindd_can_contact_domain(child->domain)) { + DEBUG(10,("machine_password_change_handler: Removing myself since I " + "do not have an incoming trust to domain %s\n", + child->domain->name)); + return; + } + + result = cm_connect_netlogon(child->domain, &netlogon_pipe); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to connect netlogon pipe: %s\n", + nt_errstr(result))); + return; + } + + frame = talloc_stackframe(); + + result = trust_pw_find_change_and_store_it(netlogon_pipe, + frame, + child->domain->name); + TALLOC_FREE(frame); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("machine_password_change_handler: " + "failed to change machine password: %s\n", + nt_errstr(result))); + } else { + DEBUG(10,("machine_password_change_handler: " + "successfully changed machine password\n")); + } + + child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL, + next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); +} + /* Deal with a request to go offline. */ static void child_msg_offline(struct messaging_context *msg, @@ -1138,6 +1243,21 @@ static bool fork_domain_child(struct winbindd_child *child) child); } + if (child->domain && child->domain->primary && + lp_server_role() == ROLE_DOMAIN_MEMBER) { + + struct timeval next_change; + + if (calculate_next_machine_pwd_change(child->domain->name, + &next_change)) { + child->machine_password_change_event = event_add_timed( + winbind_event_context(), NULL, next_change, + "machine_password_change_handler", + machine_password_change_handler, + child); + } + } + while (1) { int ret; diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 01a4054d44..50936c01a3 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -86,10 +86,7 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do "good" : "bad")); done: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, nt_errstr(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Checking the trust account password returned %s\n", state->response.data.auth.nt_status_string)); diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 0f9f1e1621..a7911f60aa 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -176,7 +176,7 @@ static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx, } fill_domain_username(state->response.data.auth.unix_username, - nt_domain, nt_username, True); + nt_domain, nt_username, true); DEBUG(5,("Setting unix username to [%s]\n", state->response.data.auth.unix_username)); @@ -310,8 +310,8 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, TALLOC_FREE(frame); - status = sid_array_from_info3(mem_ctx, info3, - &token->user_sids, + status = sid_array_from_info3(mem_ctx, info3, + &token->user_sids, &token->num_sids, true, false); if (!NT_STATUS_IS_OK(status)) { @@ -338,13 +338,13 @@ static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } } - + /* Do not distinguish this error from a wrong username/pw */ return NT_STATUS_LOGON_FAILURE; } -struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, +struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, const char *domain_name) { struct winbindd_domain *domain; @@ -353,7 +353,7 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, domain = find_domain_from_name_noinit(domain_name); if (domain == NULL) { DEBUG(3, ("Authentication for domain [%s] refused " - "as it is not a trusted domain\n", + "as it is not a trusted domain\n", domain_name)); } return domain; @@ -370,27 +370,30 @@ struct winbindd_domain *find_auth_domain(struct winbindd_cli_state *state, if (state->request.flags & WBFLAG_PAM_CONTACT_TRUSTDOM) { domain = find_domain_from_name_noinit(domain_name); if (domain == NULL) { - DEBUG(3, ("Authentication for domain [%s] skipped " - "as it is not a trusted domain\n", + DEBUG(3, ("Authentication for domain [%s] skipped " + "as it is not a trusted domain\n", domain_name)); } else { return domain; - } + } } return find_our_domain(); } -static void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) +static void fill_in_password_policy(struct winbindd_response *r, + const struct samr_DomInfo1 *p) { - resp->data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); - - /* we might have given a more useful error above */ - if (*resp->data.auth.error_string == '\0') - fstrcpy(resp->data.auth.error_string, - get_friendly_nt_error_msg(result)); - resp->data.auth.pam_error = nt_status_to_pam(result); + r->data.auth.policy.min_length_password = + p->min_password_length; + r->data.auth.policy.password_history = + p->password_history_length; + r->data.auth.policy.password_properties = + p->password_properties; + r->data.auth.policy.expire = + nt_time_to_unix_abs((NTTIME *)&(p->max_password_age)); + r->data.auth.policy.min_passwordage = + nt_time_to_unix_abs((NTTIME *)&(p->min_password_age)); } static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, @@ -402,9 +405,9 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, if ( !winbindd_can_contact_domain( domain ) ) { DEBUG(5,("fillup_password_policy: No inbound trust to " - "contact domain %s\n", domain->name)); + "contact domain %s\n", domain->name)); return NT_STATUS_NOT_SUPPORTED; - } + } methods = domain->methods; @@ -413,22 +416,13 @@ static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, return status; } - state->response.data.auth.policy.min_length_password = - password_policy.min_password_length; - state->response.data.auth.policy.password_history = - password_policy.password_history_length; - state->response.data.auth.policy.password_properties = - password_policy.password_properties; - state->response.data.auth.policy.expire = - nt_time_to_unix_abs((NTTIME *)&(password_policy.max_password_age)); - state->response.data.auth.policy.min_passwordage = - nt_time_to_unix_abs((NTTIME *)&(password_policy.min_password_age)); + fill_in_password_policy(&state->response, &password_policy); return NT_STATUS_OK; } -static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, +static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, uint16 *lockout_threshold) { struct winbindd_methods *methods; @@ -449,8 +443,8 @@ static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain return NT_STATUS_OK; } -static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, - TALLOC_CTX *mem_ctx, +static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, + TALLOC_CTX *mem_ctx, uint32 *password_properties) { struct winbindd_methods *methods; @@ -473,7 +467,7 @@ static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, #ifdef HAVE_KRB5 -static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, +static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, const char *type, uid_t uid, bool *internal_ccache) @@ -484,7 +478,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, const char *gen_cc = NULL; - *internal_ccache = True; + *internal_ccache = true; if (uid == -1) { goto memory_ccache; @@ -503,7 +497,7 @@ static const char *generate_krb5_ccache(TALLOC_CTX *mem_ctx, goto memory_ccache; } - *internal_ccache = False; + *internal_ccache = false; goto done; memory_ccache: @@ -532,11 +526,11 @@ static void setup_return_cc_name(struct winbindd_cli_state *state, const char *c if (!strequal(type, "FILE") && !strequal(type, "WRFILE")) { - DEBUG(10,("won't return krbccname for a %s type ccache\n", + DEBUG(10,("won't return krbccname for a %s type ccache\n", type)); return; } - + fstrcpy(state->response.data.auth.krb5ccname, cc); } @@ -577,13 +571,13 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, uid_t uid = -1; ADS_STRUCT *ads; time_t time_offset = 0; - bool internal_ccache = True; + bool internal_ccache = true; ZERO_STRUCTP(info3); *info3 = NULL; - - /* 1st step: + + /* 1st step: * prepare a krb5_cc_cache string for the user */ uid = get_uid_from_state(state); @@ -593,31 +587,31 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, cc = generate_krb5_ccache(state->mem_ctx, state->request.data.auth.krb5_cc_type, - state->request.data.auth.uid, + state->request.data.auth.uid, &internal_ccache); if (cc == NULL) { return NT_STATUS_NO_MEMORY; } - /* 2nd step: + /* 2nd step: * get kerberos properties */ - + if (domain->private_data) { ads = (ADS_STRUCT *)domain->private_data; - time_offset = ads->auth.time_offset; + time_offset = ads->auth.time_offset; } - /* 3rd step: + /* 3rd step: * do kerberos auth and setup ccache as the user */ parse_domain_user(state->request.data.auth.user, name_domain, name_user); realm = domain->alt_name; strupper_m(realm); - - principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm); + + principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm); if (principal_s == NULL) { return NT_STATUS_NO_MEMORY; } @@ -644,8 +638,8 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, &ticket_lifetime, &renewal_until, cc, - True, - True, + true, + true, WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, info3); if (!internal_ccache) { @@ -665,7 +659,7 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, * environment */ if (!internal_ccache) { - + setup_return_cc_name(state, cc); result = add_ccache_to_list(principal_s, @@ -676,11 +670,11 @@ static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, uid, time(NULL), ticket_lifetime, - renewal_until, - False); + renewal_until, + false); if (!NT_STATUS_IS_OK(result)) { - DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n", + DEBUG(10,("winbindd_raw_kerberos_login: failed to add ccache to list: %s\n", nt_errstr(result))); } } else { @@ -737,12 +731,12 @@ static bool check_request_flags(uint32_t flags) ( (flags & flags_edata) == WBFLAG_PAM_INFO3_NDR) || ( (flags & flags_edata) == WBFLAG_PAM_INFO3_TEXT)|| !(flags & flags_edata) ) { - return True; + return true; } DEBUG(1,("check_request_flags: invalid request flags[0x%08X]\n",flags)); - return False; + return false; } /**************************************************************** @@ -836,7 +830,7 @@ void winbindd_pam_auth(struct winbindd_cli_state *state) } /* Parse domain and username */ - + ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR ); if (!canonicalize_username(state->request.data.auth.user, @@ -869,7 +863,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, struct netr_SamInfo3 **info3) { NTSTATUS result = NT_STATUS_LOGON_FAILURE; - uint16 max_allowed_bad_attempts; + uint16 max_allowed_bad_attempts; fstring name_domain, name_user; DOM_SID sid; enum lsa_SidType type; @@ -878,7 +872,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, const uint8 *cached_salt; struct netr_SamInfo3 *my_info3; time_t kickoff_time, must_change_time; - bool password_good = False; + bool password_good = false; #ifdef HAVE_KRB5 struct winbindd_tdc_domain *tdc_domain = NULL; #endif @@ -890,7 +884,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, DEBUG(10,("winbindd_dual_pam_auth_cached\n")); /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); @@ -908,10 +902,10 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, return NT_STATUS_LOGON_FAILURE; } - result = winbindd_get_creds(domain, - state->mem_ctx, - &sid, - &my_info3, + result = winbindd_get_creds(domain, + state->mem_ctx, + &sid, + &my_info3, &cached_nt_pass, &cached_salt); if (!NT_STATUS_IS_OK(result)) { @@ -936,42 +930,42 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, E_md5hash(cached_salt, new_nt_pass, salted_hash); password_good = (memcmp(cached_nt_pass, salted_hash, NT_HASH_LEN) == 0) ? - True : False; + true : false; } else { /* Old cached cred - direct store of nt_hash (bad bad bad !). */ password_good = (memcmp(cached_nt_pass, new_nt_pass, NT_HASH_LEN) == 0) ? - True : False; + true : false; } if (password_good) { /* User *DOES* know the password, update logon_time and reset * bad_pw_count */ - + my_info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT; - + if (my_info3->base.acct_flags & ACB_AUTOLOCK) { return NT_STATUS_ACCOUNT_LOCKED_OUT; } - + if (my_info3->base.acct_flags & ACB_DISABLED) { return NT_STATUS_ACCOUNT_DISABLED; } - + if (my_info3->base.acct_flags & ACB_WSTRUST) { return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; } - + if (my_info3->base.acct_flags & ACB_SVRTRUST) { return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; } - + if (my_info3->base.acct_flags & ACB_DOMTRUST) { return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT; } if (!(my_info3->base.acct_flags & ACB_NORMAL)) { - DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n", + DEBUG(0,("winbindd_dual_pam_auth_cached: whats wrong with that one?: 0x%08x\n", my_info3->base.acct_flags)); return NT_STATUS_LOGON_FAILURE; } @@ -988,7 +982,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, /* return NT_STATUS_PASSWORD_EXPIRED; */ goto success; } - + #ifdef HAVE_KRB5 if ((state->request.flags & WBFLAG_PAM_KRB5) && ((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) && @@ -999,7 +993,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, char *realm = NULL; const char *principal_s = NULL; const char *service = NULL; - bool internal_ccache = False; + bool internal_ccache = false; uid = get_uid_from_state(state); if (uid == -1) { @@ -1041,7 +1035,7 @@ NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, time(NULL), time(NULL) + lp_winbind_cache_time(), time(NULL) + WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, - True); + true); if (!NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_cached: failed " @@ -1113,7 +1107,7 @@ failed: my_info3); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n", + DEBUG(0,("winbindd_dual_pam_auth_cached: failed to update creds %s\n", nt_errstr(result))); } @@ -1121,7 +1115,7 @@ failed: } NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, - struct winbindd_cli_state *state, + struct winbindd_cli_state *state, struct netr_SamInfo3 **info3) { struct winbindd_domain *contact_domain; @@ -1129,38 +1123,38 @@ NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, NTSTATUS result; DEBUG(10,("winbindd_dual_pam_auth_kerberos\n")); - + /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + } else { if (is_myname(name_domain)) { DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + contact_domain = find_domain_from_name(name_domain); if (contact_domain == NULL) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); contact_domain = find_our_domain(); } } - if (contact_domain->initialized && + if (contact_domain->initialized && contact_domain->active_directory) { goto try_login; } @@ -1212,13 +1206,13 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, *info3 = NULL; DEBUG(10,("winbindd_dual_pam_auth_samlogon\n")); - + /* Parse domain and username */ - + parse_domain_user(state->request.data.auth.user, name_domain, name_user); /* do password magic */ - + generate_random_buffer(chal, 8); if (lp_client_ntlmv2_auth()) { @@ -1226,17 +1220,17 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, DATA_BLOB names_blob; DATA_BLOB nt_response; DATA_BLOB lm_response; - server_chal = data_blob_talloc(state->mem_ctx, chal, 8); - + server_chal = data_blob_talloc(state->mem_ctx, chal, 8); + /* note that the 'workgroup' here is a best guess - we don't know the server's domain at this point. The 'server name' is also - dodgy... + dodgy... */ names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); - - if (!SMBNTLMv2encrypt(name_user, name_domain, - state->request.data.auth.pass, - &server_chal, + + if (!SMBNTLMv2encrypt(name_user, name_domain, + state->request.data.auth.pass, + &server_chal, &names_blob, &lm_response, &nt_response, NULL)) { data_blob_free(&names_blob); @@ -1255,35 +1249,35 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, data_blob_free(&nt_response); } else { - if (lp_client_lanman_auth() - && SMBencrypt(state->request.data.auth.pass, - chal, + if (lp_client_lanman_auth() + && SMBencrypt(state->request.data.auth.pass, + chal, local_lm_response)) { - lm_resp = data_blob_talloc(state->mem_ctx, - local_lm_response, + lm_resp = data_blob_talloc(state->mem_ctx, + local_lm_response, sizeof(local_lm_response)); } else { lm_resp = data_blob_null; } - SMBNTencrypt(state->request.data.auth.pass, + SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response); - nt_resp = data_blob_talloc(state->mem_ctx, - local_nt_response, + nt_resp = data_blob_talloc(state->mem_ctx, + local_nt_response, sizeof(local_nt_response)); } - + /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } - + } else { if (is_myname(name_domain)) { DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); @@ -1300,7 +1294,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, netlogon_fn_t logon_fn; ZERO_STRUCTP(my_info3); - retry = False; + retry = false; result = cm_connect_netlogon(contact_domain, &netlogon_pipe); @@ -1312,7 +1306,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, /* It is really important to try SamLogonEx here, * because in a clustered environment, we want to use * one machine account from multiple physical - * computers. + * computers. * * With a normal SamLogon call, we must keep the * credentials chain updated and intact between all @@ -1326,7 +1320,7 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, * When using SamLogonEx, the credentials are not * supplied, but the session key is implied by the * wrapping SamLogon context. - * + * * -- abartlet 21 April 2008 */ @@ -1351,8 +1345,8 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, && 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; + contact_domain->can_do_samlogon_ex = false; + retry = true; continue; } @@ -1361,15 +1355,15 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, our connection. */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { - retry = True; + retry = true; continue; } - + /* if we get access denied, a possible cause was that we had and open connection to the DC, but someone changed our machine account password out from underneath us using 'net rpc changetrustpw' */ - + if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth: sam_logon returned " "ACCESS_DENIED. Maybe the trust account " @@ -1377,16 +1371,16 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, "Killing connections to domain %s\n", name_domain)); invalidate_cm_connection(&contact_domain->conn); - retry = True; - } - + retry = true; + } + } while ( (attempts < 2) && retry ); /* handle the case where a NT4 DC does not fill in the acct_flags in * the samlogon reply info3. When accurate info3 is required by the * caller, we look up the account flags ourselve - gd */ - if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && + if ((state->request.flags & WBFLAG_PAM_INFO3_TEXT) && NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) { struct rpc_pipe_client *samr_pipe; @@ -1395,11 +1389,11 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, NTSTATUS status_tmp; uint32 acct_flags; - status_tmp = cm_connect_sam(contact_domain, state->mem_ctx, + status_tmp = cm_connect_sam(contact_domain, state->mem_ctx, &samr_pipe, &samr_domain_handle); if (!NT_STATUS_IS_OK(status_tmp)) { - DEBUG(3, ("could not open handle to SAMR pipe: %s\n", + DEBUG(3, ("could not open handle to SAMR pipe: %s\n", nt_errstr(status_tmp))); goto done; } @@ -1448,10 +1442,10 @@ done: } enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_LOGON_FAILURE; - NTSTATUS krb5_result = NT_STATUS_OK; + NTSTATUS krb5_result = NT_STATUS_OK; fstring name_domain, name_user; struct netr_SamInfo3 *info3 = NULL; @@ -1470,12 +1464,12 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, } /* Parse domain and username */ - + ws_name_return( state->request.data.auth.user, WB_REPLACE_CHAR ); parse_domain_user(state->request.data.auth.user, name_domain, name_user); - if (domain->online == False) { + if (domain->online == false) { result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; if (domain->startup) { /* Logons are very important to users. If we're offline and @@ -1494,11 +1488,11 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, /* Check for Kerberos authentication */ if (domain->online && (state->request.flags & WBFLAG_PAM_KRB5)) { - + result = winbindd_dual_pam_auth_kerberos(domain, state, &info3); /* save for later */ krb5_result = result; - + if (NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_kerberos succeeded\n")); @@ -1512,7 +1506,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { DEBUG(10,("winbindd_dual_pam_auth_kerberos setting domain to offline\n")); set_domain_offline( domain ); - goto cached_logon; + goto cached_logon; } /* there are quite some NT_STATUS errors where there is no @@ -1531,7 +1525,7 @@ enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) { goto process_result; } - + if (state->request.flags & WBFLAG_PAM_FALLBACK_AFTER_KRB5) { DEBUG(3,("falling back to samlogon\n")); goto sam_logon; @@ -1544,7 +1538,7 @@ sam_logon: /* Check for Samlogon authentication */ if (domain->online) { result = winbindd_dual_pam_auth_samlogon(domain, state, &info3); - + if (NT_STATUS_IS_OK(result)) { DEBUG(10,("winbindd_dual_pam_auth_samlogon succeeded\n")); /* add the Krb5 err if we have one */ @@ -1552,18 +1546,18 @@ sam_logon: info3->base.user_flags |= LOGON_KRB5_FAIL_CLOCK_SKEW; } goto process_result; - } + } - DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n", + DEBUG(10,("winbindd_dual_pam_auth_samlogon failed: %s\n", nt_errstr(result))); if (NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS) || NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT) || - NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) + NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { DEBUG(10,("winbindd_dual_pam_auth_samlogon setting domain to offline\n")); set_domain_offline( domain ); - goto cached_logon; + goto cached_logon; } if (domain->online) { @@ -1574,9 +1568,9 @@ sam_logon: cached_logon: /* Check for Cached logons */ - if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) && + if (!domain->online && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN) && lp_winbind_offline_logon()) { - + result = winbindd_dual_pam_auth_cached(domain, state, &info3); if (NT_STATUS_IS_OK(result)) { @@ -1591,7 +1585,7 @@ cached_logon: process_result: if (NT_STATUS_IS_OK(result)) { - + DOM_SID user_sid; /* In all codepaths where result == NT_STATUS_OK info3 must have @@ -1608,19 +1602,19 @@ process_result: this is our primary domain so we don't invalidate the cache entry by storing the seq_num for the wrong domain). */ - if ( domain->primary ) { + if ( domain->primary ) { sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid); - cache_name2sid(domain, name_domain, name_user, + cache_name2sid(domain, name_domain, name_user, SID_NAME_USER, &user_sid); } - + /* Check if the user is in the right group */ if (!NT_STATUS_IS_OK(result = check_info3_in_group(state->mem_ctx, info3, state->request.data.auth.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n", - state->request.data.auth.user, + state->request.data.auth.user, state->request.data.auth.require_membership_of_sid)); goto done; } @@ -1665,8 +1659,8 @@ process_result: /* This is not entirely correct I believe, but it is consistent. Only apply the password policy settings - too warn users for our own domain. Cannot obtain these - from trusted DCs all the time so don't do it at all. + too warn users for our own domain. Cannot obtain these + from trusted DCs all the time so don't do it at all. -- jerry */ result = NT_STATUS_NOT_SUPPORTED; @@ -1674,16 +1668,16 @@ process_result: result = fillup_password_policy(our_domain, state); } - if (!NT_STATUS_IS_OK(result) - && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ) + if (!NT_STATUS_IS_OK(result) + && !NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) ) { - DEBUG(10,("Failed to get password policies for domain %s: %s\n", + DEBUG(10,("Failed to get password policies for domain %s: %s\n", domain->name, nt_errstr(result))); goto done; } } - result = NT_STATUS_OK; + result = NT_STATUS_OK; } done: @@ -1692,26 +1686,20 @@ done: (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { result = NT_STATUS_NO_LOGON_SERVERS; } - - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - /* we might have given a more useful error above */ - if (!*state->response.data.auth.error_string) - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", - state->request.data.auth.user, + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", + state->request.data.auth.user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } /********************************************************************** - Challenge Response Authentication Protocol + Challenge Response Authentication Protocol **********************************************************************/ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) @@ -1775,7 +1763,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) set_auth_errors(&state->response, result); DEBUG(5, ("CRAP authentication for %s\\%s returned %s (PAM: %d)\n", state->request.data.auth_crap.domain, - state->request.data.auth_crap.user, + state->request.data.auth_crap.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -1784,7 +1772,7 @@ void winbindd_pam_auth_crap(struct winbindd_cli_state *state) enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result; struct netr_SamInfo3 *info3 = NULL; @@ -1817,7 +1805,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, } else if (lp_winbind_use_default_domain()) { name_domain = lp_workgroup(); } else { - DEBUG(5,("no domain specified with username (%s) - failing auth\n", + DEBUG(5,("no domain specified with username (%s) - failing auth\n", name_user)); result = NT_STATUS_NO_SUCH_USER; goto done; @@ -1825,7 +1813,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, name_domain, name_user)); - + if (*state->request.data.auth_crap.workstation) { workstation = state->request.data.auth_crap.workstation; } else { @@ -1834,8 +1822,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp) || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) { - DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", - state->request.data.auth_crap.lm_resp_len, + DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", + state->request.data.auth_crap.lm_resp_len, state->request.data.auth_crap.nt_resp_len)); result = NT_STATUS_INVALID_PARAMETER; goto done; @@ -1847,11 +1835,11 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.nt_resp_len); /* what domain should we contact? */ - + if ( IS_DC ) { if (!(contact_domain = find_domain_from_name(name_domain))) { - DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", - state->request.data.auth_crap.user, name_domain, name_user, name_domain)); + DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", + state->request.data.auth_crap.user, name_domain, name_user, name_domain)); result = NT_STATUS_NO_SUCH_USER; goto done; } @@ -1867,7 +1855,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, do { netlogon_fn_t logon_fn; - retry = False; + retry = false; netlogon_pipe = NULL; result = cm_connect_netlogon(contact_domain, &netlogon_pipe); @@ -1887,7 +1875,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.logon_parameters, contact_domain->dcname, name_user, - name_domain, + name_domain, /* Bug #3248 - found by Stefan Burkei. */ workstation, /* We carefully set this above so use it... */ state->request.data.auth_crap.chal, @@ -1899,8 +1887,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, && 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; + contact_domain->can_do_samlogon_ex = false; + retry = true; continue; } @@ -1911,14 +1899,14 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, our connection. */ if (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { - retry = True; + retry = true; continue; } /* if we get access denied, a possible cause was that we had and open connection to the DC, but someone changed our machine account password out from underneath us using 'net rpc changetrustpw' */ - + if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { DEBUG(3,("winbindd_pam_auth: sam_logon returned " "ACCESS_DENIED. Maybe the trust account " @@ -1926,8 +1914,8 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, "Killing connections to domain %s\n", name_domain)); invalidate_cm_connection(&contact_domain->conn); - retry = True; - } + retry = true; + } } while ( (attempts < 2) && retry ); @@ -1942,7 +1930,7 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, state->request.data.auth_crap.require_membership_of_sid))) { DEBUG(3, ("User %s is not in the required group (%s), so " "crap authentication is rejected\n", - state->request.data.auth_crap.user, + state->request.data.auth_crap.user, state->request.data.auth_crap.require_membership_of_sid)); goto done; } @@ -1965,21 +1953,14 @@ done: result = nt_status_squash(result); } - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - - /* we might have given a more useful error above */ - if (!*state->response.data.auth.error_string) { - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - } - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n", name_domain, name_user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2002,7 +1983,7 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state) set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s" "(PAM: %d)\n", - state->request.data.auth.user, + state->request.data.auth.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -2012,8 +1993,8 @@ void winbindd_pam_chauthtok(struct winbindd_cli_state *state) contact_domain = find_domain_from_name(domain); if (!contact_domain) { set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); - DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", - state->request.data.chauthtok.user, domain, user, domain)); + DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n", + state->request.data.chauthtok.user, domain, user, domain)); request_error(state); return; } @@ -2028,7 +2009,7 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact char *newpass = NULL; POLICY_HND dom_pol; struct rpc_pipe_client *cli; - bool got_info = False; + bool got_info = false; struct samr_DomInfo1 *info = NULL; struct samr_ChangeReject *reject = NULL; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -2068,21 +2049,13 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact /* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */ if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) { - state->response.data.auth.policy.min_length_password = - info->min_password_length; - state->response.data.auth.policy.password_history = - info->password_history_length; - state->response.data.auth.policy.password_properties = - info->password_properties; - state->response.data.auth.policy.expire = - nt_time_to_unix_abs((NTTIME *)&info->max_password_age); - state->response.data.auth.policy.min_passwordage = - nt_time_to_unix_abs((NTTIME *)&info->min_password_age); + + fill_in_password_policy(&state->response, info); state->response.data.auth.reject_reason = reject->reason; - got_info = True; + got_info = true; } /* only fallback when the chgpasswd_user3 call is not supported */ @@ -2092,18 +2065,18 @@ enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n", nt_errstr(result))); - + result = rpccli_samr_chgpasswd_user2(cli, state->mem_ctx, user, newpass, oldpass); /* Windows 2000 returns NT_STATUS_ACCOUNT_RESTRICTION. Map to the same status code as Windows 2003. */ if ( NT_STATUS_EQUAL(NT_STATUS_ACCOUNT_RESTRICTION, result ) ) { - result = NT_STATUS_PASSWORD_RESTRICTION; + result = NT_STATUS_PASSWORD_RESTRICTION; } } -done: +done: if (NT_STATUS_IS_OK(result) && (state->request.flags & WBFLAG_PAM_CACHED_LOGIN)) { @@ -2151,7 +2124,7 @@ done: if (!NT_STATUS_IS_OK(result) && !got_info && contact_domain) { NTSTATUS policy_ret; - + policy_ret = fillup_password_policy(contact_domain, state); /* failure of this is non critical, it will just provide no @@ -2166,17 +2139,14 @@ done: process_result: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", domain, user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2211,7 +2181,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) } if ((sys_getpeereid(state->sock, &caller_uid)) != 0) { - DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", + DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", strerror(errno))); goto failed; } @@ -2247,7 +2217,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) } enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, - struct winbindd_cli_state *state) + struct winbindd_cli_state *state) { NTSTATUS result = NT_STATUS_NOT_SUPPORTED; @@ -2265,7 +2235,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, } #ifdef HAVE_KRB5 - + if (state->request.data.logoff.uid < 0) { DEBUG(0,("winbindd_pam_logoff: invalid uid\n")); goto process_result; @@ -2280,7 +2250,7 @@ enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, goto process_result; } - if (!ccache_entry_identical(state->request.data.logoff.user, + if (!ccache_entry_identical(state->request.data.logoff.user, state->request.data.logoff.uid, state->request.data.logoff.krb5ccname)) { DEBUG(0,("winbindd_pam_logoff: cached entry differs.\n")); @@ -2302,10 +2272,7 @@ process_result: winbindd_delete_memory_creds(state->request.data.logoff.user); - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + set_auth_errors(&state->response, result); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } @@ -2322,12 +2289,12 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state) sizeof(state->request.data.chng_pswd_auth_crap.user)-1]=0; state->request.data.chng_pswd_auth_crap.domain[ sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0; - + DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n", (unsigned long)state->pid, state->request.data.chng_pswd_auth_crap.domain, state->request.data.chng_pswd_auth_crap.user)); - + if (*state->request.data.chng_pswd_auth_crap.domain != '\0') { domain_name = state->request.data.chng_pswd_auth_crap.domain; } else if (lp_winbind_use_default_domain()) { @@ -2347,7 +2314,7 @@ void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state) set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER); DEBUG(5, ("CRAP change password for %s\\%s returned %s (PAM: %d)\n", state->request.data.chng_pswd_auth_crap.domain, - state->request.data.chng_pswd_auth_crap.user, + state->request.data.chng_pswd_auth_crap.user, state->response.data.auth.nt_status_string, state->response.data.auth.pam_error)); request_error(state); @@ -2373,7 +2340,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0; *domain = 0; *user = 0; - + DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n", (unsigned long)state->pid, state->request.data.chng_pswd_auth_crap.domain, @@ -2411,7 +2378,7 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, domain, user)); - + /* Change password */ new_nt_password = data_blob_talloc( state->mem_ctx, @@ -2450,18 +2417,15 @@ enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domai cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc, new_lm_password, old_lm_hash_enc); - done: - state->response.data.auth.nt_status = NT_STATUS_V(result); - fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result)); - fstrcpy(state->response.data.auth.error_string, - get_friendly_nt_error_msg(result)); - state->response.data.auth.pam_error = nt_status_to_pam(result); + done: + + set_auth_errors(&state->response, result); - DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, - ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", + DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, + ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n", domain, user, state->response.data.auth.nt_status_string, - state->response.data.auth.pam_error)); + state->response.data.auth.pam_error)); return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 0e0db3e859..c5b7b07931 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -590,6 +590,7 @@ void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); void winbindd_set_locator_kdc_envs(const struct winbindd_domain *domain); void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain); +void set_auth_errors(struct winbindd_response *resp, NTSTATUS result); /* The following definitions come from winbindd/winbindd_wins.c */ diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 77b17787c9..83c5053f78 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -180,11 +180,11 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const domain->initialized = False; domain->online = is_internal_domain(sid); domain->check_online_timeout = 0; + domain->dc_probe_pid = (pid_t)-1; if (sid) { sid_copy(&domain->sid, sid); } - /* Link to domain list */ DLIST_ADD_END(_domain_list, domain, struct winbindd_domain *); @@ -1544,3 +1544,15 @@ void winbindd_unset_locator_kdc_env(const struct winbindd_domain *domain) } #endif /* HAVE_KRB5_LOCATE_PLUGIN_H */ + +void set_auth_errors(struct winbindd_response *resp, NTSTATUS result) +{ + resp->data.auth.nt_status = NT_STATUS_V(result); + fstrcpy(resp->data.auth.nt_status_string, nt_errstr(result)); + + /* we might have given a more useful error above */ + if (*resp->data.auth.error_string == '\0') + fstrcpy(resp->data.auth.error_string, + get_friendly_nt_error_msg(result)); + resp->data.auth.pam_error = nt_status_to_pam(result); +} |