summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/pam_winbind.c111
-rw-r--r--source3/nsswitch/pam_winbind.h28
-rw-r--r--source3/nsswitch/wb_common.c20
-rw-r--r--source3/nsswitch/wbinfo.c66
-rw-r--r--source3/nsswitch/winbind_nss_solaris.c25
5 files changed, 183 insertions, 67 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 95b3d23dd4..c28c5d2697 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -12,6 +12,78 @@
#include "pam_winbind.h"
+static const char *_pam_error_code_str(int err)
+{
+ switch (err) {
+ case PAM_SUCCESS:
+ return "PAM_SUCCESS";
+ case PAM_OPEN_ERR:
+ return "PAM_OPEN_ERR";
+ case PAM_SYMBOL_ERR:
+ return "PAM_SYMBOL_ERR";
+ case PAM_SERVICE_ERR:
+ return "PAM_SERVICE_ERR";
+ case PAM_SYSTEM_ERR:
+ return "PAM_SYSTEM_ERR";
+ case PAM_BUF_ERR:
+ return "PAM_BUF_ERR";
+ case PAM_PERM_DENIED:
+ return "PAM_PERM_DENIED";
+ case PAM_AUTH_ERR:
+ return "PAM_AUTH_ERR";
+ case PAM_CRED_INSUFFICIENT:
+ return "PAM_CRED_INSUFFICIENT";
+ case PAM_AUTHINFO_UNAVAIL:
+ return "PAM_AUTHINFO_UNAVAIL";
+ case PAM_USER_UNKNOWN:
+ return "PAM_USER_UNKNOWN";
+ case PAM_MAXTRIES:
+ return "PAM_MAXTRIES";
+ case PAM_NEW_AUTHTOK_REQD:
+ return "PAM_NEW_AUTHTOK_REQD";
+ case PAM_ACCT_EXPIRED:
+ return "PAM_ACCT_EXPIRED";
+ case PAM_SESSION_ERR:
+ return "PAM_SESSION_ERR";
+ case PAM_CRED_UNAVAIL:
+ return "PAM_CRED_UNAVAIL";
+ case PAM_CRED_EXPIRED:
+ return "PAM_CRED_EXPIRED";
+ case PAM_CRED_ERR:
+ return "PAM_CRED_ERR";
+ case PAM_NO_MODULE_DATA:
+ return "PAM_NO_MODULE_DATA";
+ case PAM_CONV_ERR:
+ return "PAM_CONV_ERR";
+ case PAM_AUTHTOK_ERR:
+ return "PAM_AUTHTOK_ERR";
+ case PAM_AUTHTOK_RECOVERY_ERR:
+ return "PAM_AUTHTOK_RECOVERY_ERR";
+ case PAM_AUTHTOK_LOCK_BUSY:
+ return "PAM_AUTHTOK_LOCK_BUSY";
+ case PAM_AUTHTOK_DISABLE_AGING:
+ return "PAM_AUTHTOK_DISABLE_AGING";
+ case PAM_TRY_AGAIN:
+ return "PAM_TRY_AGAIN";
+ case PAM_IGNORE:
+ return "PAM_IGNORE";
+ case PAM_ABORT:
+ return "PAM_ABORT";
+ case PAM_AUTHTOK_EXPIRED:
+ return "PAM_AUTHTOK_EXPIRED";
+ case PAM_MODULE_UNKNOWN:
+ return "PAM_MODULE_UNKNOWN";
+ case PAM_BAD_ITEM:
+ return "PAM_BAD_ITEM";
+ case PAM_CONV_AGAIN:
+ return "PAM_CONV_AGAIN";
+ case PAM_INCOMPLETE:
+ return "PAM_INCOMPLETE";
+ default:
+ return NULL;
+ }
+}
+
#define _PAM_LOG_FUNCTION_ENTER(function, ctx) \
do { \
_pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] ENTER: " \
@@ -22,7 +94,8 @@
#define _PAM_LOG_FUNCTION_LEAVE(function, ctx, retval) \
do { \
_pam_log_debug(ctx, LOG_DEBUG, "[pamh: %p] LEAVE: " \
- function " returning %d", ctx->pamh, retval); \
+ function " returning %d (%s)", ctx->pamh, retval, \
+ _pam_error_code_str(retval)); \
_pam_log_state(ctx); \
} while (0)
@@ -698,8 +771,7 @@ static int pam_winbind_request_log(struct pwb_context *ctx,
/**
* send a password expiry message if required
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param next_change expected (calculated) next expiry date.
* @param already_expired pointer to a boolean to indicate if the password is
* already expired.
@@ -760,8 +832,7 @@ static bool _pam_send_password_expiry_message(struct pwb_context *ctx,
/**
* Send a warning if the password expires in the near future
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param response The full authentication response structure.
* @param already_expired boolean, is the pwd already expired?
*
@@ -850,8 +921,7 @@ static bool safe_append_string(char *dest,
/**
* Convert a names into a SID string, appending it to a buffer.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param user User in PAM request.
* @param name Name to convert.
* @param sid_list_buffer Where to append the string sid.
@@ -906,8 +976,7 @@ static bool winbind_name_to_sid_string(struct pwb_context *ctx,
/**
* Convert a list of names into a list of sids.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param user User in PAM request.
* @param name_list List of names or string sids, separated by commas.
* @param sid_list_buffer Where to put the list of string sids.
@@ -971,8 +1040,7 @@ out:
/**
* put krb5ccname variable into environment
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param krb5ccname env variable retrieved from winbindd.
*
* @return void.
@@ -1010,8 +1078,7 @@ static void _pam_setup_krb5_env(struct pwb_context *ctx,
/**
* Set string into the PAM stack.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param data_name Key name for pam_set_data.
* @param value String value.
*
@@ -1042,8 +1109,7 @@ static void _pam_set_data_string(struct pwb_context *ctx,
/**
* Set info3 strings into the PAM stack.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param data_name Key name for pam_set_data.
* @param value String value.
*
@@ -1082,8 +1148,7 @@ static void _pam_free_data_info3(pam_handle_t *pamh)
/**
* Send PAM_ERROR_MSG for cached or grace logons.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param username User in PAM request.
* @param info3_user_flgs Info3 flags containing logon type bits.
*
@@ -1120,8 +1185,7 @@ static void _pam_warn_logon_type(struct pwb_context *ctx,
/**
* Send PAM_ERROR_MSG for krb5 errors.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param username User in PAM request.
* @param info3_user_flgs Info3 flags containing logon type bits.
*
@@ -1869,8 +1933,7 @@ static int get_warn_pwd_expire_from_config(struct pwb_context *ctx)
/**
* Retrieve the winbind separator.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
*
* @return string separator character. NULL on failure.
*/
@@ -1894,8 +1957,7 @@ static char winbind_get_separator(struct pwb_context *ctx)
/**
* Convert a upn to a name.
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param upn USer UPN to be trabslated.
*
* @return converted name. NULL pointer on failure. Caller needs to free.
@@ -2370,8 +2432,7 @@ out:
* evaluate whether we need to re-authenticate with kerberos after a
* password change
*
- * @param pamh PAM handle
- * @param ctrl PAM winbind options.
+ * @param ctx PAM winbind context.
* @param user The username
*
* @return boolean Returns true if required, false if not.
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
index be17a6fe45..c8c1910641 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -83,20 +83,20 @@ do { \
#include <security/pam_ext.h>
#endif
-#define WINBIND_DEBUG_ARG (1<<0)
-#define WINBIND_USE_AUTHTOK_ARG (1<<1)
-#define WINBIND_UNKNOWN_OK_ARG (1<<2)
-#define WINBIND_TRY_FIRST_PASS_ARG (1<<3)
-#define WINBIND_USE_FIRST_PASS_ARG (1<<4)
-#define WINBIND__OLD_PASSWORD (1<<5)
-#define WINBIND_REQUIRED_MEMBERSHIP (1<<6)
-#define WINBIND_KRB5_AUTH (1<<7)
-#define WINBIND_KRB5_CCACHE_TYPE (1<<8)
-#define WINBIND_CACHED_LOGIN (1<<9)
-#define WINBIND_CONFIG_FILE (1<<10)
-#define WINBIND_SILENT (1<<11)
-#define WINBIND_DEBUG_STATE (1<<12)
-#define WINBIND_WARN_PWD_EXPIRE (1<<13)
+#define WINBIND_DEBUG_ARG 0x00000001
+#define WINBIND_USE_AUTHTOK_ARG 0x00000002
+#define WINBIND_UNKNOWN_OK_ARG 0x00000004
+#define WINBIND_TRY_FIRST_PASS_ARG 0x00000008
+#define WINBIND_USE_FIRST_PASS_ARG 0x00000010
+#define WINBIND__OLD_PASSWORD 0x00000020
+#define WINBIND_REQUIRED_MEMBERSHIP 0x00000040
+#define WINBIND_KRB5_AUTH 0x00000080
+#define WINBIND_KRB5_CCACHE_TYPE 0x00000100
+#define WINBIND_CACHED_LOGIN 0x00000200
+#define WINBIND_CONFIG_FILE 0x00000400
+#define WINBIND_SILENT 0x00000800
+#define WINBIND_DEBUG_STATE 0x00001000
+#define WINBIND_WARN_PWD_EXPIRE 0x00002000
/*
* here is the string to inform the user that the new passwords they
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index b113fc3336..6e6d2bbbf8 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -176,11 +176,13 @@ static int winbind_named_pipe_sock(const char *dir)
/* Check permissions on unix socket directory */
if (lstat(dir, &st) == -1) {
+ errno = ENOENT;
return -1;
}
if (!S_ISDIR(st.st_mode) ||
(st.st_uid != 0 && st.st_uid != geteuid())) {
+ errno = ENOENT;
return -1;
}
@@ -199,6 +201,7 @@ static int winbind_named_pipe_sock(const char *dir)
the winbindd daemon is not running. */
if (lstat(path, &st) == -1) {
+ errno = ENOENT;
SAFE_FREE(path);
return -1;
}
@@ -208,6 +211,7 @@ static int winbind_named_pipe_sock(const char *dir)
if (!S_ISSOCK(st.st_mode) ||
(st.st_uid != 0 && st.st_uid != geteuid())) {
+ errno = ENOENT;
return -1;
}
@@ -368,6 +372,7 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
restart:
if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
+ errno = ENOENT;
return -1;
}
@@ -564,7 +569,11 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv,
if (winbind_write_sock(request, sizeof(*request),
request->wb_flags & WBFLAG_RECURSE,
- need_priv) == -1) {
+ need_priv) == -1)
+ {
+ /* Set ENOENT for consistency. Required by some apps */
+ errno = ENOENT;
+
return NSS_STATUS_UNAVAIL;
}
@@ -572,7 +581,11 @@ NSS_STATUS winbindd_send_request(int req_type, int need_priv,
(winbind_write_sock(request->extra_data.data,
request->extra_len,
request->wb_flags & WBFLAG_RECURSE,
- need_priv) == -1)) {
+ need_priv) == -1))
+ {
+ /* Set ENOENT for consistency. Required by some apps */
+ errno = ENOENT;
+
return NSS_STATUS_UNAVAIL;
}
@@ -596,6 +609,9 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response)
/* Wait for reply */
if (winbindd_read_reply(response) == -1) {
+ /* Set ENOENT for consistency. Required by some apps */
+ errno = ENOENT;
+
return NSS_STATUS_UNAVAIL;
}
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index c1d41a53fd..463d9233d0 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -879,6 +879,33 @@ static bool wbinfo_lookupname(const char *full_name)
return true;
}
+static char *wbinfo_prompt_pass(const char *prefix,
+ const char *username)
+{
+ char *prompt;
+ const char *ret = NULL;
+
+ prompt = talloc_asprintf(talloc_tos(), "Enter %s's ", username);
+ if (!prompt) {
+ return NULL;
+ }
+ if (prefix) {
+ prompt = talloc_asprintf_append(prompt, "%s ", prefix);
+ if (!prompt) {
+ return NULL;
+ }
+ }
+ prompt = talloc_asprintf_append(prompt, "password: ");
+ if (!prompt) {
+ return NULL;
+ }
+
+ ret = getpass(prompt);
+ TALLOC_FREE(prompt);
+
+ return SMB_STRDUP(ret);
+}
+
/* Authenticate a user with a plaintext password */
static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
@@ -887,6 +914,7 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
struct winbindd_response response;
NSS_STATUS result;
char *p;
+ char *password;
/* Send off request */
@@ -900,8 +928,12 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
fstrcpy(request.data.auth.user, username);
fstrcpy(request.data.auth.pass, p + 1);
*p = '%';
- } else
+ } else {
fstrcpy(request.data.auth.user, username);
+ password = wbinfo_prompt_pass(NULL, username);
+ fstrcpy(request.data.auth.pass, password);
+ SAFE_FREE(password);
+ }
request.flags = flags;
@@ -947,7 +979,7 @@ static bool wbinfo_auth(char *username)
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
char *s = NULL;
char *p = NULL;
- const char *password = NULL;
+ char *password = NULL;
char *name = NULL;
if ((s = SMB_STRDUP(username)) == NULL) {
@@ -957,16 +989,9 @@ static bool wbinfo_auth(char *username)
if ((p = strchr(s, '%')) != NULL) {
*p = 0;
p++;
- password = p;
+ password = SMB_STRDUP(p);
} else {
- char *prompt;
- asprintf(&prompt, "Enter %s's password:", username);
- if (!prompt) {
- return false;
- }
-
- password = getpass(prompt);
- SAFE_FREE(prompt);
+ password = wbinfo_prompt_pass(NULL, username);
}
name = s;
@@ -985,6 +1010,7 @@ static bool wbinfo_auth(char *username)
#endif
SAFE_FREE(s);
+ SAFE_FREE(password);
return WBC_ERROR_IS_OK(wbc_status);
}
@@ -1001,26 +1027,18 @@ static bool wbinfo_auth_crap(char *username)
DATA_BLOB nt = data_blob_null;
fstring name_user;
fstring name_domain;
- fstring pass;
+ char *pass;
char *p;
p = strchr(username, '%');
if (p) {
*p = 0;
- fstrcpy(pass, p + 1);
+ pass = SMB_STRDUP(p + 1);
} else {
- char *prompt;
- asprintf(&prompt, "Enter %s's password:", username);
- if (!prompt) {
- return false;
- }
-
- fstrcpy(pass, getpass(prompt));
- SAFE_FREE(prompt);
-
+ pass = wbinfo_prompt_pass(NULL, username);
}
-
+
parse_wbinfo_domain_user(username, name_domain, name_user);
params.account_name = name_user;
@@ -1049,6 +1067,7 @@ static bool wbinfo_auth_crap(char *username)
&lm, &nt, NULL)) {
data_blob_free(&names_blob);
data_blob_free(&server_chal);
+ SAFE_FREE(pass);
return false;
}
data_blob_free(&names_blob);
@@ -1093,6 +1112,7 @@ static bool wbinfo_auth_crap(char *username)
data_blob_free(&nt);
data_blob_free(&lm);
+ SAFE_FREE(pass);
return WBC_ERROR_IS_OK(wbc_status);
}
diff --git a/source3/nsswitch/winbind_nss_solaris.c b/source3/nsswitch/winbind_nss_solaris.c
index 5a72393788..865b6ebbb0 100644
--- a/source3/nsswitch/winbind_nss_solaris.c
+++ b/source3/nsswitch/winbind_nss_solaris.c
@@ -359,7 +359,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response
int addrcount = 0;
int len = 0;
struct in_addr *addrp;
+#if defined(AF_INET6)
struct in6_addr *addrp6;
+#endif
int i;
/* response is tab separated list of ip addresses with hostname
@@ -391,7 +393,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response
addrp -= addrcount;
he->h_addr_list = (char **)ROUND_DOWN(addrp, sizeof (char*));
he->h_addr_list -= addrcount+1;
- } else {
+ }
+#if defined(AF_INET6)
+ else {
he->h_length = sizeof(struct in6_addr);
addrp6 = (struct in6_addr *)ROUND_DOWN(buffer + buflen,
sizeof(struct in6_addr));
@@ -399,6 +403,7 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response
he->h_addr_list = (char **)ROUND_DOWN(addrp6, sizeof (char*));
he->h_addr_list -= addrcount+1;
}
+#endif
/* buffer too small?! */
if((char *)he->h_addr_list < buffer ) {
@@ -418,7 +423,9 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response
argp->erange = 1;
return NSS_STR_PARSE_ERANGE;
}
- } else {
+ }
+#if defined(AF_INET6)
+ else {
he->h_addr_list[i] = (char *)&addrp6[i];
if (strchr(data, ':') != 0) {
if (inet_pton(AF_INET6, data, &addrp6[i]) != 1) {
@@ -434,6 +441,7 @@ parse_response(int af, nss_XbyY_args_t* argp, struct winbindd_response *response
IN6_INADDR_TO_V4MAPPED(&in4, &addrp6[i]);
}
}
+#endif
data = p+1;
}
@@ -481,6 +489,7 @@ _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
AF_INET or for AF_INET6 and AI_ALL|AI_V4MAPPED we have to map
IPv4 to IPv6.
*/
+#if defined(AF_INET6)
#ifdef HAVE_NSS_XBYY_KEY_IPNODE
af = argp->key.ipnode.af_family;
if(af == AF_INET6 && argp->key.ipnode.flags == 0) {
@@ -491,6 +500,7 @@ _nss_winbind_ipnodes_getbyname(nss_backend_t* be, void *args)
/* I'm not that sure if this is correct, but... */
af = AF_INET6;
#endif
+#endif
strncpy(request.data.winsreq, argp->key.name, sizeof(request.data.winsreq) - 1);
request.data.winsreq[sizeof(request.data.winsreq) - 1] = '\0';
@@ -539,6 +549,7 @@ _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
ZERO_STRUCT(response);
ZERO_STRUCT(request);
+#if defined(AF_INET6)
/* winbindd currently does not resolve IPv6 */
if(argp->key.hostaddr.type == AF_INET6) {
argp->h_errno = NO_DATA;
@@ -546,7 +557,15 @@ _nss_winbind_hosts_getbyaddr(nss_backend_t* be, void *args)
}
p = inet_ntop(argp->key.hostaddr.type, argp->key.hostaddr.addr,
- request.data.winsreq, INET6_ADDRSTRLEN);
+ request.data.winsreq, sizeof request.data.winsreq);
+#else
+ snprintf(request.data.winsreq, sizeof request.data.winsreq,
+ "%u.%u.%u.%u",
+ ((unsigned char *)argp->key.hostaddr.addr)[0],
+ ((unsigned char *)argp->key.hostaddr.addr)[1],
+ ((unsigned char *)argp->key.hostaddr.addr)[2],
+ ((unsigned char *)argp->key.hostaddr.addr)[3]);
+#endif
ret = winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response);