summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
authorKarolin Seeger <kseeger@samba.org>2008-02-29 10:44:38 +0100
committerKarolin Seeger <kseeger@samba.org>2008-02-29 10:44:38 +0100
commitc4fbe2846231a6b322c1094c6a1dbf93b7305768 (patch)
tree09eb77a294f4acda131b41fe4c9bec4ed175eb16 /source3/nsswitch
parent1a6415fc77c708b87c8e2ce6e7828f486ffc87ac (diff)
parent695b6662abe64a40061bfa05ede12173fc4b1945 (diff)
downloadsamba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.gz
samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.tar.bz2
samba-c4fbe2846231a6b322c1094c6a1dbf93b7305768.zip
Merge commit 'origin/v3-2-test' into v3-2-stable
Conflicts: WHATSNEW.txt (This used to be commit a390bcf9403df4cf4d5eef42b35ebccbe253882e)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/libwbclient/wbc_pam.c375
-rw-r--r--source3/nsswitch/libwbclient/wbc_pwd.c20
-rw-r--r--source3/nsswitch/libwbclient/wbc_sid.c11
-rw-r--r--source3/nsswitch/libwbclient/wbclient.c47
-rw-r--r--source3/nsswitch/libwbclient/wbclient.h161
-rw-r--r--source3/nsswitch/pam_winbind.c13
-rw-r--r--source3/nsswitch/pam_winbind.h24
-rw-r--r--source3/nsswitch/wb_common.c27
-rw-r--r--source3/nsswitch/wbinfo.c392
-rw-r--r--source3/nsswitch/winbind_client.h11
-rw-r--r--source3/nsswitch/winbind_krb5_locator.c8
-rw-r--r--source3/nsswitch/winbind_struct_protocol.h1
-rw-r--r--source3/nsswitch/wins.c8
13 files changed, 814 insertions, 284 deletions
diff --git a/source3/nsswitch/libwbclient/wbc_pam.c b/source3/nsswitch/libwbclient/wbc_pam.c
index 7f7c7b8140..1164ab173a 100644
--- a/source3/nsswitch/libwbclient/wbc_pam.c
+++ b/source3/nsswitch/libwbclient/wbc_pam.c
@@ -34,32 +34,389 @@
wbcErr wbcAuthenticateUser(const char *username,
const char *password)
{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcAuthUserParams params;
+
+ ZERO_STRUCT(params);
+
+ params.account_name = username;
+ params.level = WBC_AUTH_USER_LEVEL_PLAIN;
+ params.password.plaintext = password;
+
+ wbc_status = wbcAuthenticateUserEx(&params, NULL, NULL);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+done:
+ return wbc_status;
+}
+
+static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
+ const struct winbindd_response *resp,
+ struct wbcAuthUserInfo **_i)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcAuthUserInfo *i;
+ struct wbcDomainSid domain_sid;
+ char *p;
+ uint32_t sn = 0;
+ uint32_t j;
+
+ i = talloc(mem_ctx, struct wbcAuthUserInfo);
+ BAIL_ON_PTR_ERROR(i, wbc_status);
+
+ i->user_flags = resp->data.auth.info3.user_flgs;
+
+ i->account_name = talloc_strdup(i, resp->data.auth.info3.user_name);
+ BAIL_ON_PTR_ERROR(i->account_name, wbc_status);
+ i->user_principal= NULL;
+ i->full_name = talloc_strdup(i, resp->data.auth.info3.full_name);
+ BAIL_ON_PTR_ERROR(i->full_name, wbc_status);
+ i->domain_name = talloc_strdup(i, resp->data.auth.info3.logon_dom);
+ BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
+ i->dns_domain_name= NULL;
+
+ i->acct_flags = resp->data.auth.info3.acct_flags;
+ memcpy(i->user_session_key,
+ resp->data.auth.user_session_key,
+ sizeof(i->user_session_key));
+ memcpy(i->lm_session_key,
+ resp->data.auth.first_8_lm_hash,
+ sizeof(i->lm_session_key));
+
+ i->logon_count = resp->data.auth.info3.logon_count;
+ i->bad_password_count = resp->data.auth.info3.bad_pw_count;
+
+ i->logon_time = resp->data.auth.info3.logon_time;
+ i->logoff_time = resp->data.auth.info3.logoff_time;
+ i->kickoff_time = resp->data.auth.info3.kickoff_time;
+ i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time;
+ i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time;
+ i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time;
+
+ i->logon_server = talloc_strdup(i, resp->data.auth.info3.logon_srv);
+ BAIL_ON_PTR_ERROR(i->logon_server, wbc_status);
+ i->logon_script = talloc_strdup(i, resp->data.auth.info3.logon_script);
+ BAIL_ON_PTR_ERROR(i->logon_script, wbc_status);
+ i->profile_path = talloc_strdup(i, resp->data.auth.info3.profile_path);
+ BAIL_ON_PTR_ERROR(i->profile_path, wbc_status);
+ i->home_directory= talloc_strdup(i, resp->data.auth.info3.home_dir);
+ BAIL_ON_PTR_ERROR(i->home_directory, wbc_status);
+ i->home_drive = talloc_strdup(i, resp->data.auth.info3.dir_drive);
+ BAIL_ON_PTR_ERROR(i->home_drive, wbc_status);
+
+ i->num_sids = 2;
+ i->num_sids += resp->data.auth.info3.num_groups;
+ i->num_sids += resp->data.auth.info3.num_other_sids;
+
+ i->sids = talloc_array(i, struct wbcSidWithAttr, i->num_sids);
+ BAIL_ON_PTR_ERROR(i->sids, wbc_status);
+
+ wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid,
+ &domain_sid);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+#define _SID_COMPOSE(s, d, r, a) { \
+ (s).sid = d; \
+ if ((s).sid.num_auths < MAXSUBAUTHS) { \
+ (s).sid.sub_auths[(s).sid.num_auths++] = r; \
+ } else { \
+ wbc_status = WBC_ERR_INVALID_SID; \
+ BAIL_ON_WBC_ERROR(wbc_status); \
+ } \
+ (s).attributes = a; \
+} while (0)
+
+ sn = 0;
+ _SID_COMPOSE(i->sids[sn], domain_sid,
+ resp->data.auth.info3.user_rid,
+ 0);
+ sn++;
+ _SID_COMPOSE(i->sids[sn], domain_sid,
+ resp->data.auth.info3.group_rid,
+ 0);
+ sn++;
+
+ p = (char *)resp->extra_data.data;
+ if (!p) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ for (j=0; j < resp->data.auth.info3.num_groups; j++) {
+ uint32_t rid;
+ uint32_t attrs;
+ int ret;
+ char *s = p;
+ char *e = strchr(p, '\n');
+ if (!e) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ e[0] = '\0';
+ p = &e[1];
+
+ ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs);
+ if (ret != 2) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ _SID_COMPOSE(i->sids[sn], domain_sid,
+ rid, attrs);
+ sn++;
+ }
+
+ for (j=0; j < resp->data.auth.info3.num_other_sids; j++) {
+ uint32_t attrs;
+ int ret;
+ char *s = p;
+ char *a;
+ char *e = strchr(p, '\n');
+ if (!e) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ e[0] = '\0';
+ p = &e[1];
+
+ e = strchr(s, ':');
+ if (!e) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ e[0] = '\0';
+ a = &e[1];
+
+ ret = sscanf(a, "0x%08X",
+ &attrs);
+ if (ret != 1) {
+ wbc_status = WBC_INVALID_RESPONSE;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ wbc_status = wbcStringToSid(s, &i->sids[sn].sid);
+ BAIL_ON_WBC_ERROR(wbc_status);
+
+ i->sids[sn].attributes = attrs;
+ sn++;
+ }
+
+ i->num_sids = sn;
+
+ *_i = i;
+ i = NULL;
+done:
+ talloc_free(i);
+ return wbc_status;
+}
+
+static wbcErr wbc_create_error_info(TALLOC_CTX *mem_ctx,
+ const struct winbindd_response *resp,
+ struct wbcAuthErrorInfo **_e)
+{
+ wbcErr wbc_status = WBC_ERR_SUCCESS;
+ struct wbcAuthErrorInfo *e;
+
+ e = talloc(mem_ctx, struct wbcAuthErrorInfo);
+ BAIL_ON_PTR_ERROR(e, wbc_status);
+
+ e->nt_status = resp->data.auth.nt_status;
+ e->pam_error = resp->data.auth.pam_error;
+ e->nt_string = talloc_strdup(e, resp->data.auth.nt_status_string);
+ BAIL_ON_PTR_ERROR(e->nt_string, wbc_status);
+
+ e->display_string = talloc_strdup(e, resp->data.auth.error_string);
+ BAIL_ON_PTR_ERROR(e->display_string, wbc_status);
+
+ *_e = e;
+ e = NULL;
+
+done:
+ talloc_free(e);
+ return wbc_status;
+}
+
+/** @brief Authenticate with more detailed information
+ *
+ * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH
+ * is not supported yet
+ * @param info Output details on WBC_ERR_SUCCESS
+ * @param error Output details on WBC_ERR_AUTH_ERROR
+ *
+ * @return #wbcErr
+ **/
+
+wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
+ struct wbcAuthUserInfo **info,
+ struct wbcAuthErrorInfo **error)
+{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ int cmd = 0;
struct winbindd_request request;
struct winbindd_response response;
- if (!username) {
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ if (error) {
+ *error = NULL;
+ }
+
+ if (!params) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (!params->account_name) {
wbc_status = WBC_ERR_INVALID_PARAM;
BAIL_ON_WBC_ERROR(wbc_status);
}
/* Initialize request */
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
+ switch (params->level) {
+ case WBC_AUTH_USER_LEVEL_PLAIN:
+ cmd = WINBINDD_PAM_AUTH;
+ request.flags = WBFLAG_PAM_INFO3_TEXT |
+ WBFLAG_PAM_USER_SESSION_KEY |
+ WBFLAG_PAM_LMKEY;
+
+ if (!params->password.plaintext) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->domain_name && params->domain_name[0]) {
+ /* We need to get the winbind separator :-( */
+ struct winbindd_response sep_response;
- /* dst is already null terminated from the memset above */
+ ZERO_STRUCT(sep_response);
- strncpy(request.data.auth.user, username,
- sizeof(request.data.auth.user)-1);
- strncpy(request.data.auth.pass, password,
- sizeof(request.data.auth.user)-1);
+ wbc_status = wbcRequestResponse(WINBINDD_INFO,
+ NULL, &sep_response);
+ BAIL_ON_WBC_ERROR(wbc_status);
- wbc_status = wbcRequestResponse(WINBINDD_PAM_AUTH,
+ snprintf(request.data.auth.user,
+ sizeof(request.data.auth.user)-1,
+ "%s%c%s",
+ params->domain_name,
+ sep_response.data.info.winbind_separator,
+ params->account_name);
+ } else {
+ strncpy(request.data.auth.user,
+ params->account_name,
+ sizeof(request.data.auth.user)-1);
+ }
+ strncpy(request.data.auth.pass,
+ params->password.plaintext,
+ sizeof(request.data.auth.user)-1);
+ break;
+
+ case WBC_AUTH_USER_LEVEL_HASH:
+ wbc_status = WBC_ERR_NOT_IMPLEMENTED;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ break;
+
+ case WBC_AUTH_USER_LEVEL_RESPONSE:
+ cmd = WINBINDD_PAM_AUTH_CRAP;
+ request.flags = WBFLAG_PAM_INFO3_TEXT |
+ WBFLAG_PAM_USER_SESSION_KEY |
+ WBFLAG_PAM_LMKEY;
+
+ if (params->password.response.lm_length &&
+ params->password.response.lm_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ if (params->password.response.lm_length == 0 &&
+ params->password.response.lm_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (params->password.response.nt_length &&
+ !params->password.response.nt_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+ if (params->password.response.nt_length == 0&&
+ params->password.response.nt_data) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ strncpy(request.data.auth_crap.user,
+ params->account_name,
+ sizeof(request.data.auth_crap.user)-1);
+ if (params->domain_name) {
+ strncpy(request.data.auth_crap.domain,
+ params->domain_name,
+ sizeof(request.data.auth_crap.domain)-1);
+ }
+ if (params->workstation_name) {
+ strncpy(request.data.auth_crap.workstation,
+ params->workstation_name,
+ sizeof(request.data.auth_crap.workstation)-1);
+ }
+
+ request.data.auth_crap.logon_parameters =
+ params->parameter_control;
+
+ memcpy(request.data.auth_crap.chal,
+ params->password.response.challenge,
+ sizeof(request.data.auth_crap.chal));
+
+ request.data.auth_crap.lm_resp_len =
+ MIN(params->password.response.lm_length,
+ sizeof(request.data.auth_crap.lm_resp));
+ request.data.auth_crap.nt_resp_len =
+ MIN(params->password.response.nt_length,
+ sizeof(request.data.auth_crap.nt_resp));
+ if (params->password.response.lm_data) {
+ memcpy(request.data.auth_crap.lm_resp,
+ params->password.response.lm_data,
+ request.data.auth_crap.lm_resp_len);
+ }
+ if (params->password.response.nt_data) {
+ memcpy(request.data.auth_crap.nt_resp,
+ params->password.response.nt_data,
+ request.data.auth_crap.nt_resp_len);
+ }
+ break;
+ default:
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ if (cmd == 0) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ wbc_status = wbcRequestResponse(cmd,
&request,
&response);
+ if (response.data.auth.nt_status != 0) {
+ if (error) {
+ wbc_status = wbc_create_error_info(NULL,
+ &response,
+ error);
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
+ wbc_status = WBC_ERR_AUTH_ERROR;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
BAIL_ON_WBC_ERROR(wbc_status);
+ if (info) {
+ wbc_status = wbc_create_auth_info(NULL,
+ &response,
+ info);
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
done:
+
return wbc_status;
}
diff --git a/source3/nsswitch/libwbclient/wbc_pwd.c b/source3/nsswitch/libwbclient/wbc_pwd.c
index b24e198bc5..b7febcce0c 100644
--- a/source3/nsswitch/libwbclient/wbc_pwd.c
+++ b/source3/nsswitch/libwbclient/wbc_pwd.c
@@ -209,16 +209,16 @@ wbcErr wbcGetgrnam(const char *name, struct group **grp)
struct winbindd_request request;
struct winbindd_response response;
- if (!name || !grp) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
/* Initialize request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ if (!name || !grp) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
/* dst is already null terminated from the memset above */
strncpy(request.data.groupname, name, sizeof(request.data.groupname)-1);
@@ -254,16 +254,16 @@ wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
struct winbindd_request request;
struct winbindd_response response;
- if (!grp) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
/* Initialize request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ if (!grp) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
request.data.gid = gid;
wbc_status = wbcRequestResponse(WINBINDD_GETGRGID,
diff --git a/source3/nsswitch/libwbclient/wbc_sid.c b/source3/nsswitch/libwbclient/wbc_sid.c
index abe1457cc1..0519d8bf9f 100644
--- a/source3/nsswitch/libwbclient/wbc_sid.c
+++ b/source3/nsswitch/libwbclient/wbc_sid.c
@@ -311,16 +311,16 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
char *domain_name = NULL;
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- if (!dom_sid || (num_rids == 0)) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
/* Initialise request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
+ if (!dom_sid || (num_rids == 0)) {
+ wbc_status = WBC_ERR_INVALID_PARAM;
+ BAIL_ON_WBC_ERROR(wbc_status);
+ }
+
wbc_status = wbcSidToString(dom_sid, &sid_string);
BAIL_ON_WBC_ERROR(wbc_status);
@@ -355,6 +355,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
&request,
&response);
talloc_free(ridlist);
+ BAIL_ON_WBC_ERROR(wbc_status);
domain_name = talloc_strdup(NULL, response.data.domain_name);
BAIL_ON_PTR_ERROR(domain_name, wbc_status);
diff --git a/source3/nsswitch/libwbclient/wbclient.c b/source3/nsswitch/libwbclient/wbclient.c
index 321a7db669..e17296283f 100644
--- a/source3/nsswitch/libwbclient/wbclient.c
+++ b/source3/nsswitch/libwbclient/wbclient.c
@@ -59,11 +59,7 @@ wbcErr wbcRequestResponse(int cmd,
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
NSS_STATUS nss_status;
- if (!request || !response) {
- wbc_status = WBC_ERR_INVALID_PARAM;
- BAIL_ON_WBC_ERROR(wbc_status);
- }
-
+ /* for some calls the request and/or response cna be NULL */
nss_status = winbindd_request_response(cmd, request, response);
@@ -72,20 +68,55 @@ wbcErr wbcRequestResponse(int cmd,
wbc_status = WBC_ERR_SUCCESS;
break;
case NSS_STATUS_UNAVAIL:
- return WBC_ERR_WINBIND_NOT_AVAILABLE;
+ wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE;
break;
case NSS_STATUS_NOTFOUND:
- return WBC_ERR_DOMAIN_NOT_FOUND;
+ wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
break;
default:
wbc_status = WBC_ERR_NSS_ERROR;
break;
}
-done:
return wbc_status;
}
+/** @brief Translate an error value into a string
+ *
+ * @param error
+ *
+ * @return a pointer to a static string
+ **/
+const char *wbcErrorString(wbcErr error)
+{
+ switch (error) {
+ case WBC_ERR_SUCCESS:
+ return "WBC_ERR_SUCCESS";
+ case WBC_ERR_NOT_IMPLEMENTED:
+ return "WBC_ERR_NOT_IMPLEMENTED";
+ case WBC_ERR_UNKNOWN_FAILURE:
+ return "WBC_ERR_UNKNOWN_FAILURE";
+ case WBC_ERR_NO_MEMORY:
+ return "WBC_ERR_NO_MEMORY";
+ case WBC_ERR_INVALID_SID:
+ return "WBC_ERR_INVALID_SID";
+ case WBC_ERR_INVALID_PARAM:
+ return "WBC_ERR_INVALID_PARAM";
+ case WBC_ERR_WINBIND_NOT_AVAILABLE:
+ return "WBC_ERR_WINBIND_NOT_AVAILABLE";
+ case WBC_ERR_DOMAIN_NOT_FOUND:
+ return "WBC_ERR_DOMAIN_NOT_FOUND";
+ case WBC_INVALID_RESPONSE:
+ return "WBC_INVALID_RESPONSE";
+ case WBC_ERR_NSS_ERROR:
+ return "WBC_ERR_NSS_ERROR";
+ case WBC_ERR_AUTH_ERROR:
+ return "WBC_ERR_AUTH_ERROR";
+ }
+
+ return "unknown wbcErr value";
+};
+
/** @brief Free library allocated memory
*
* @param *p Pointer to free
diff --git a/source3/nsswitch/libwbclient/wbclient.h b/source3/nsswitch/libwbclient/wbclient.h
index 0b256d343f..c01db9618d 100644
--- a/source3/nsswitch/libwbclient/wbclient.h
+++ b/source3/nsswitch/libwbclient/wbclient.h
@@ -41,14 +41,15 @@ enum _wbcErrType {
WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/
WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/
WBC_INVALID_RESPONSE, /**< Winbind returned an invalid response **/
- WBC_ERR_NSS_ERROR /**< NSS_STATUS error **/
+ WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/
+ WBC_ERR_AUTH_ERROR /**< Authentication failed **/
};
typedef enum _wbcErrType wbcErr;
#define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS)
-char *wbcErrorString(wbcErr error);
+const char *wbcErrorString(wbcErr error);
/*
* Data types used by the Winbind Client API
@@ -88,6 +89,25 @@ enum wbcSidType {
};
/**
+ * @brief Security Identifier with attributes
+ **/
+
+struct wbcSidWithAttr {
+ struct wbcDomainSid sid;
+ uint32_t attributes;
+};
+
+/* wbcSidWithAttr->attributes */
+
+#define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001
+#define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002
+#define WBC_SID_ATTR_GROUP_ENABLED 0x00000004
+#define WBC_SID_ATTR_GROUP_OWNER 0x00000008
+#define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010
+#define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000
+#define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000
+
+/**
* @brief Domain Information
**/
@@ -104,6 +124,140 @@ struct wbcDomainInfo {
#define WBC_DOMINFO_AD 0x00000002
#define WBC_DOMINFO_PRIMARY 0x00000004
+/**
+ * @brief Auth User Parameters
+ **/
+
+struct wbcAuthUserParams {
+ const char *account_name;
+ const char *domain_name;
+ const char *workstation_name;
+
+ uint32_t flags;
+
+ uint32_t parameter_control;
+
+ enum wbcAuthUserLevel {
+ WBC_AUTH_USER_LEVEL_PLAIN = 1,
+ WBC_AUTH_USER_LEVEL_HASH = 2,
+ WBC_AUTH_USER_LEVEL_RESPONSE = 3
+ } level;
+ union {
+ const char *plaintext;
+ struct {
+ uint8_t nt_hash[16];
+ uint8_t lm_hash[16];
+ } hash;
+ struct {
+ uint8_t challenge[8];
+ uint32_t nt_length;
+ uint8_t *nt_data;
+ uint32_t lm_length;
+ uint8_t *lm_data;
+ } response;
+ } password;
+};
+
+/* wbcAuthUserParams->parameter_control */
+
+#define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002
+#define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004
+#define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008
+#define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020
+#define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200
+#define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800
+
+/* wbcAuthUserParams->flags */
+
+#define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001
+
+/**
+ * @brief Auth User Information
+ *
+ * Some of the strings are maybe NULL
+ **/
+
+struct wbcAuthUserInfo {
+ uint32_t user_flags;
+
+ char *account_name;
+ char *user_principal;
+ char *full_name;
+ char *domain_name;
+ char *dns_domain_name;
+
+ uint32_t acct_flags;
+ uint8_t user_session_key[16];
+ uint8_t lm_session_key[8];
+
+ uint16_t logon_count;
+ uint16_t bad_password_count;
+
+ uint64_t logon_time;
+ uint64_t logoff_time;
+ uint64_t kickoff_time;
+ uint64_t pass_last_set_time;
+ uint64_t pass_can_change_time;
+ uint64_t pass_must_change_time;
+
+ char *logon_server;
+ char *logon_script;
+ char *profile_path;
+ char *home_directory;
+ char *home_drive;
+
+ /*
+ * the 1st one is the account sid
+ * the 2nd one is the primary_group sid
+ * followed by the rest of the groups
+ */
+ uint32_t num_sids;
+ struct wbcSidWithAttr *sids;
+};
+
+/* wbcAuthUserInfo->user_flags */
+
+#define WBC_AUTH_USER_INFO_GUEST 0x00000001
+#define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002
+#define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004
+#define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008
+#define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020
+#define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040
+#define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080
+#define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100
+#define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200
+#define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400
+#define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000
+
+/* wbcAuthUserInfo->acct_flags */
+
+#define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */
+#define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */
+#define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */
+#define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */
+#define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */
+#define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */
+#define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */
+#define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */
+#define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */
+#define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */
+#define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */
+#define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */
+#define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */
+#define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */
+#define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */
+#define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */
+#define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */
+#define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */
+#define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */
+
+struct wbcAuthErrorInfo {
+ uint32_t nt_status;
+ char *nt_string;
+ int32_t pam_error;
+ char *display_string;
+};
+
/*
* Memory Management
*/
@@ -205,5 +359,8 @@ wbcErr wbcDomainSequenceNumbers(void);
wbcErr wbcAuthenticateUser(const char *username,
const char *password);
+wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params,
+ struct wbcAuthUserInfo **info,
+ struct wbcAuthErrorInfo **error);
#endif /* _WBCLIENT_H */
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c
index 4d019072ac..81f5227410 100644
--- a/source3/nsswitch/pam_winbind.c
+++ b/source3/nsswitch/pam_winbind.c
@@ -1341,9 +1341,10 @@ static int winbind_auth_request(pam_handle_t * pamh,
/* If winbindd returned a username, return the pointer to it
* here. */
- if (user_ret && response.extra_data.data) {
+ if (user_ret && response.data.auth.unix_username[0]) {
/* We have to trust it's a null terminated string. */
- *user_ret = (char *)response.extra_data.data;
+ *user_ret = strndup(response.data.auth.unix_username,
+ sizeof(response.data.auth.unix_username) - 1);
}
}
@@ -1431,22 +1432,22 @@ static int winbind_chauthtok_request(pam_handle_t * pamh,
switch (reject_reason) {
case -1:
break;
- case REJECT_REASON_OTHER:
+ case SAMR_REJECT_OTHER:
if ((min_pwd_age > 0) &&
(pwd_last_set + min_pwd_age > time(NULL))) {
PAM_WB_REMARK_DIRECT(pamh, ctrl,
"NT_STATUS_PWD_TOO_RECENT");
}
break;
- case REJECT_REASON_TOO_SHORT:
+ case SAMR_REJECT_TOO_SHORT:
PAM_WB_REMARK_DIRECT(pamh, ctrl,
"NT_STATUS_PWD_TOO_SHORT");
break;
- case REJECT_REASON_IN_HISTORY:
+ case SAMR_REJECT_IN_HISTORY:
PAM_WB_REMARK_DIRECT(pamh, ctrl,
"NT_STATUS_PWD_HISTORY_CONFLICT");
break;
- case REJECT_REASON_NOT_COMPLEX:
+ case SAMR_REJECT_COMPLEXITY:
_make_remark(pamh, ctrl, PAM_ERROR_MSG,
"Password does not meet "
"complexity requirements");
diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h
index 59a2f39584..a1d32726f5 100644
--- a/source3/nsswitch/pam_winbind.h
+++ b/source3/nsswitch/pam_winbind.h
@@ -12,6 +12,7 @@
#define PAM_SM_AUTH
#define PAM_SM_ACCOUNT
#define PAM_SM_PASSWORD
+#define PAM_SM_SESSION
#ifndef PAM_WINBIND_CONFIG_FILE
#define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf"
@@ -179,22 +180,23 @@ do { \
};\
};
-/* from include/rpc_samr.h */
-#define DOMAIN_PASSWORD_COMPLEX 0x00000001
+/* from samr.idl */
+#define DOMAIN_PASSWORD_COMPLEX 0x00000001
-#define REJECT_REASON_OTHER 0x00000000
-#define REJECT_REASON_TOO_SHORT 0x00000001
-#define REJECT_REASON_IN_HISTORY 0x00000002
-#define REJECT_REASON_NOT_COMPLEX 0x00000005
+#define SAMR_REJECT_OTHER 0x00000000
+#define SAMR_REJECT_TOO_SHORT 0x00000001
+#define SAMR_REJECT_IN_HISTORY 0x00000002
+#define SAMR_REJECT_COMPLEXITY 0x00000005
-/* from include/smb.h */
#define ACB_PWNOEXP 0x00000200
+/* from netlogon.idl */
+#define NETLOGON_CACHED_ACCOUNT 0x00000004
+#define NETLOGON_GRACE_LOGON 0x01000000
+
/* from include/rpc_netlogon.h */
-#define LOGON_CACHED_ACCOUNT 0x00000004
-#define LOGON_GRACE_LOGON 0x01000000
#define LOGON_KRB5_FAIL_CLOCK_SKEW 0x02000000
-#define PAM_WB_CACHED_LOGON(x) (x & LOGON_CACHED_ACCOUNT)
+#define PAM_WB_CACHED_LOGON(x) (x & NETLOGON_CACHED_ACCOUNT)
#define PAM_WB_KRB5_CLOCK_SKEW(x) (x & LOGON_KRB5_FAIL_CLOCK_SKEW)
-#define PAM_WB_GRACE_LOGON(x) ((LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON) == ( x & (LOGON_CACHED_ACCOUNT|LOGON_GRACE_LOGON)))
+#define PAM_WB_GRACE_LOGON(x) ((NETLOGON_CACHED_ACCOUNT|NETLOGON_GRACE_LOGON) == ( x & (NETLOGON_CACHED_ACCOUNT|NETLOGON_GRACE_LOGON)))
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index 49a2935bff..b113fc3336 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -538,18 +538,6 @@ int winbindd_read_reply(struct winbindd_response *response)
return result1 + result2;
}
-bool winbind_env_set(void)
-{
- char *env;
-
- if ((env=getenv(WINBINDD_DONT_ENV)) != NULL) {
- if(strcmp(env, "1") == 0) {
- return true;
- }
- }
- return false;
-}
-
/*
* send simple types of requests
*/
@@ -663,21 +651,6 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
}
/*************************************************************************
- A couple of simple functions to disable winbindd lookups and re-
- enable them
- ************************************************************************/
-
-bool winbind_off(void)
-{
- return setenv(WINBINDD_DONT_ENV, "1", 1) != -1;
-}
-
-bool winbind_on(void)
-{
- return setenv(WINBINDD_DONT_ENV, "0", 1) != -1;
-}
-
-/*************************************************************************
************************************************************************/
const char *nss_err_str(NSS_STATUS ret)
diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c
index c8f8398c6f..ee51cce835 100644
--- a/source3/nsswitch/wbinfo.c
+++ b/source3/nsswitch/wbinfo.c
@@ -53,7 +53,7 @@ static char winbind_separator_int(bool strict)
}
sep = response.data.info.winbind_separator;
- got_sep = True;
+ got_sep = true;
if (!sep) {
d_fprintf(stderr, "winbind separator was NULL!\n");
@@ -69,27 +69,27 @@ static char winbind_separator_int(bool strict)
static char winbind_separator(void)
{
- return winbind_separator_int(False);
+ return winbind_separator_int(false);
}
static const char *get_winbind_domain(void)
{
- wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
struct wbcDomainInfo *dinfo = NULL;
static fstring winbind_domain;
ZERO_STRUCT(dinfo);
-
+
wbc_status = wbcDomainInfo(".", &dinfo);
if (!WBC_ERROR_IS_OK(wbc_status)) {
d_fprintf(stderr, "could not obtain winbind domain name!\n");
-
+
/* HACK: (this module should not call lp_ funtions) */
return lp_workgroup();
}
- fstrcpy(winbind_domain, dinfo->short_name);
+ fstrcpy(winbind_domain, dinfo->short_name);
wbcFreeMemory(dinfo);
@@ -99,7 +99,7 @@ static const char *get_winbind_domain(void)
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
form DOMAIN/user into a domain and a user */
-static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
+static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
fstring user)
{
@@ -110,20 +110,20 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
if ((p = strchr(domuser, '@')) != NULL) {
fstrcpy(domain, "");
fstrcpy(user, domuser);
- return True;
+ return true;
}
-
+
fstrcpy(user, domuser);
fstrcpy(domain, get_winbind_domain());
- return True;
+ return true;
}
-
+
fstrcpy(user, p+1);
fstrcpy(domain, domuser);
domain[PTR_DIFF(p, domuser)] = 0;
strupper_m(domain);
- return True;
+ return true;
}
/* pull pwent info for a given user */
@@ -131,13 +131,13 @@ static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
static bool wbinfo_get_userinfo(char *user)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct passwd *pwd = NULL;
+ struct passwd *pwd = NULL;
wbc_status = wbcGetpwnam(user, &pwd);
if (!WBC_ERROR_IS_OK(wbc_status)) {
return false;
}
-
+
d_printf("%s:%s:%d:%d:%s:%s:%s\n",
pwd->pw_name,
pwd->pw_passwd,
@@ -146,7 +146,7 @@ static bool wbinfo_get_userinfo(char *user)
pwd->pw_gecos,
pwd->pw_dir,
pwd->pw_shell);
-
+
return true;
}
@@ -154,13 +154,13 @@ static bool wbinfo_get_userinfo(char *user)
static bool wbinfo_get_uidinfo(int uid)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- struct passwd *pwd = NULL;
+ struct passwd *pwd = NULL;
wbc_status = wbcGetpwuid(uid, &pwd);
if (!WBC_ERROR_IS_OK(wbc_status)) {
return false;
}
-
+
d_printf("%s:%s:%d:%d:%s:%s:%s\n",
pwd->pw_name,
pwd->pw_passwd,
@@ -169,7 +169,7 @@ static bool wbinfo_get_uidinfo(int uid)
pwd->pw_gecos,
pwd->pw_dir,
pwd->pw_shell);
-
+
return true;
}
@@ -191,14 +191,14 @@ static bool wbinfo_get_groupinfo(char *group)
&response);
if ( result != NSS_STATUS_SUCCESS)
- return False;
+ return false;
- d_printf( "%s:%s:%d\n",
+ d_printf( "%s:%s:%d\n",
response.data.gr.gr_name,
response.data.gr.gr_passwd,
response.data.gr.gr_gid );
-
- return True;
+
+ return true;
}
/* List groups a user is a member of */
@@ -209,7 +209,7 @@ static bool wbinfo_get_usergroups(char *user)
struct winbindd_response response;
NSS_STATUS result;
int i;
-
+
ZERO_STRUCT(request);
ZERO_STRUCT(response);
@@ -220,14 +220,14 @@ static bool wbinfo_get_usergroups(char *user)
result = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
if (result != NSS_STATUS_SUCCESS)
- return False;
+ return false;
for (i = 0; i < response.data.num_entries; i++)
d_printf("%d\n", (int)((gid_t *)response.extra_data.data)[i]);
SAFE_FREE(response.extra_data.data);
- return True;
+ return true;
}
@@ -249,7 +249,7 @@ static bool wbinfo_get_usersids(char *user_sid)
result = winbindd_request_response(WINBINDD_GETUSERSIDS, &request, &response);
if (result != NSS_STATUS_SUCCESS)
- return False;
+ return false;
s = (const char *)response.extra_data.data;
for (i = 0; i < response.data.num_entries; i++) {
@@ -259,7 +259,7 @@ static bool wbinfo_get_usersids(char *user_sid)
SAFE_FREE(response.extra_data.data);
- return True;
+ return true;
}
static bool wbinfo_get_userdomgroups(const char *user_sid)
@@ -275,17 +275,17 @@ static bool wbinfo_get_userdomgroups(const char *user_sid)
fstrcpy(request.data.sid, user_sid);
result = winbindd_request_response(WINBINDD_GETUSERDOMGROUPS, &request,
- &response);
+ &response);
if (result != NSS_STATUS_SUCCESS)
- return False;
+ return false;
if (response.data.num_entries != 0)
printf("%s", (char *)response.extra_data.data);
-
+
SAFE_FREE(response.extra_data.data);
- return True;
+ return true;
}
/* Convert NetBIOS name to IP */
@@ -304,14 +304,14 @@ static bool wbinfo_wins_byname(char *name)
if (winbindd_request_response(WINBINDD_WINS_BYNAME, &request, &response) !=
NSS_STATUS_SUCCESS) {
- return False;
+ return false;
}
/* Display response */
d_printf("%s\n", response.data.winsresp);
- return True;
+ return true;
}
/* Convert IP to NetBIOS name */
@@ -330,14 +330,14 @@ static bool wbinfo_wins_byip(char *ip)
if (winbindd_request_response(WINBINDD_WINS_BYIP, &request, &response) !=
NSS_STATUS_SUCCESS) {
- return False;
+ return false;
}
/* Display response */
d_printf("%s\n", response.data.winsresp);
- return True;
+ return true;
}
/* List trusted domains */
@@ -356,7 +356,7 @@ static bool wbinfo_list_domains(bool list_all_domains)
if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
@@ -373,7 +373,7 @@ static bool wbinfo_list_domains(bool list_all_domains)
extra_data);
TALLOC_FREE(frame);
SAFE_FREE(response.extra_data.data);
- return False;
+ return false;
}
*p = 0;
d_printf("%s\n", name);
@@ -382,7 +382,7 @@ static bool wbinfo_list_domains(bool list_all_domains)
SAFE_FREE(response.extra_data.data);
}
- return True;
+ return true;
}
/* List own domain */
@@ -391,7 +391,7 @@ static bool wbinfo_list_own_domain(void)
{
d_printf("%s\n", get_winbind_domain());
- return True;
+ return true;
}
/* show sequence numbers */
@@ -410,7 +410,7 @@ static bool wbinfo_show_sequence(const char *domain)
if (winbindd_request_response(WINBINDD_SHOW_SEQUENCE, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
@@ -427,7 +427,7 @@ static bool wbinfo_show_sequence(const char *domain)
SAFE_FREE(response.extra_data.data);
}
- return True;
+ return true;
}
/* Show domain info */
@@ -449,7 +449,7 @@ static bool wbinfo_domain_info(const char *domain_name)
if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
@@ -466,7 +466,7 @@ static bool wbinfo_domain_info(const char *domain_name)
d_printf("Primary : %s\n",
response.data.domain_info.primary ? "Yes" : "No");
- return True;
+ return true;
}
/* Get a foreign DC's name */
@@ -485,14 +485,14 @@ static bool wbinfo_getdcname(const char *domain_name)
if (winbindd_request_response(WINBINDD_GETDCNAME, &request, &response) !=
NSS_STATUS_SUCCESS) {
d_fprintf(stderr, "Could not get dc name for %s\n", domain_name);
- return False;
+ return false;
}
/* Display response */
d_printf("%s\n", response.data.dc_name);
- return True;
+ return true;
}
/* Find a DC */
@@ -514,35 +514,35 @@ static bool wbinfo_dsgetdcname(const char *domain_name, uint32_t flags)
if (winbindd_request_response(WINBINDD_DSGETDCNAME, &request, &response) !=
NSS_STATUS_SUCCESS) {
d_fprintf(stderr, "Could not find dc for %s\n", domain_name);
- return False;
+ return false;
}
/* Display response */
d_printf("%s\n", response.data.dc_name);
- return True;
+ return true;
}
/* Check trust account password */
static bool wbinfo_check_secret(void)
{
- struct winbindd_response response;
- NSS_STATUS result;
+ struct winbindd_response response;
+ NSS_STATUS result;
- ZERO_STRUCT(response);
+ ZERO_STRUCT(response);
- result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response);
-
- d_printf("checking the trust secret via RPC calls %s\n",
+ result = winbindd_request_response(WINBINDD_CHECK_MACHACC, NULL, &response);
+
+ d_printf("checking the trust secret via RPC calls %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
- if (result != NSS_STATUS_SUCCESS)
- d_fprintf(stderr, "error code was %s (0x%x)\n",
- response.data.auth.nt_status_string,
+ if (result != NSS_STATUS_SUCCESS)
+ d_fprintf(stderr, "error code was %s (0x%x)\n",
+ response.data.auth.nt_status_string,
response.data.auth.nt_status);
-
+
return result == NSS_STATUS_SUCCESS;
}
@@ -562,13 +562,13 @@ static bool wbinfo_uid_to_sid(uid_t uid)
if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
d_printf("%s\n", response.data.sid.sid);
- return True;
+ return true;
}
/* Convert gid to sid */
@@ -587,13 +587,13 @@ static bool wbinfo_gid_to_sid(gid_t gid)
if (winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
d_printf("%s\n", response.data.sid.sid);
- return True;
+ return true;
}
/* Convert sid to uid */
@@ -612,13 +612,13 @@ static bool wbinfo_sid_to_uid(char *sid)
if (winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
d_printf("%d\n", (int)response.data.uid);
- return True;
+ return true;
}
static bool wbinfo_sid_to_gid(char *sid)
@@ -635,13 +635,13 @@ static bool wbinfo_sid_to_gid(char *sid)
if (winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
d_printf("%d\n", (int)response.data.gid);
- return True;
+ return true;
}
static bool wbinfo_allocate_uid(void)
@@ -649,11 +649,11 @@ static bool wbinfo_allocate_uid(void)
uid_t uid;
if (!winbind_allocate_uid(&uid))
- return False;
+ return false;
d_printf("New uid: %d\n", uid);
- return True;
+ return true;
}
static bool wbinfo_allocate_gid(void)
@@ -661,11 +661,11 @@ static bool wbinfo_allocate_gid(void)
gid_t gid;
if (!winbind_allocate_gid(&gid))
- return False;
+ return false;
d_printf("New gid: %d\n", gid);
- return True;
+ return true;
}
/* Convert sid to string */
@@ -684,15 +684,15 @@ static bool wbinfo_lookupsid(char *sid)
if (winbindd_request_response(WINBINDD_LOOKUPSID, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
- d_printf("%s%c%s %d\n", response.data.name.dom_name,
- winbind_separator(), response.data.name.name,
+ d_printf("%s%c%s %d\n", response.data.name.dom_name,
+ winbind_separator(), response.data.name.name,
response.data.name.type);
- return True;
+ return true;
}
/* Lookup a list of RIDs */
@@ -725,18 +725,18 @@ static bool wbinfo_lookuprids(char *domain, char *arg)
if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) !=
NSS_STATUS_SUCCESS) {
d_printf("Could not get domain sid for %s\n", request.domain_name);
- return False;
+ return false;
}
if (!string_to_sid(&sid, response.data.domain_info.sid)) {
d_printf("Could not convert %s to sid\n", response.data.domain_info.sid);
- return False;
+ return false;
}
mem_ctx = talloc_new(NULL);
if (mem_ctx == NULL) {
d_printf("talloc_new failed\n");
- return False;
+ return false;
}
num_rids = 0;
@@ -750,14 +750,14 @@ static bool wbinfo_lookuprids(char *domain, char *arg)
if (rids == NULL) {
TALLOC_FREE(mem_ctx);
- return False;
+ return false;
}
if (!winbind_lookup_rids(mem_ctx, &sid, num_rids, rids,
&domain_name, &names, &types)) {
d_printf("winbind_lookup_rids failed\n");
TALLOC_FREE(mem_ctx);
- return False;
+ return false;
}
d_printf("Domain: %s\n", domain_name);
@@ -768,7 +768,7 @@ static bool wbinfo_lookuprids(char *domain, char *arg)
}
TALLOC_FREE(mem_ctx);
- return True;
+ return true;
}
/* Convert string to sid */
@@ -783,18 +783,18 @@ static bool wbinfo_lookupname(char *name)
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- parse_wbinfo_domain_user(name, request.data.name.dom_name,
+ parse_wbinfo_domain_user(name, request.data.name.dom_name,
request.data.name.name);
if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Display response */
d_printf("%s %s (%d)\n", response.data.sid.sid, sid_type_lookup(response.data.sid.type), response.data.sid.type);
- return True;
+ return true;
}
/* Authenticate a user with a plaintext password */
@@ -843,8 +843,8 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
if (result == NSS_STATUS_SUCCESS) {
if (request.flags & WBFLAG_PAM_INFO3_TEXT) {
- if (response.data.auth.info3.user_flgs & LOGON_CACHED_ACCOUNT) {
- d_printf("user_flgs: LOGON_CACHED_ACCOUNT\n");
+ if (response.data.auth.info3.user_flgs & NETLOGON_CACHED_ACCOUNT) {
+ d_printf("user_flgs: NETLOGON_CACHED_ACCOUNT\n");
}
}
@@ -863,139 +863,139 @@ static bool wbinfo_auth_krb5(char *username, const char *cctype, uint32 flags)
static bool wbinfo_auth(char *username)
{
wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
- char *s = NULL;
- char *p = NULL;
- char *password = NULL;
- char *name = NULL;
+ char *s = NULL;
+ char *p = NULL;
+ const char *password = NULL;
+ char *name = NULL;
if ((s = SMB_STRDUP(username)) == NULL) {
return false;
}
if ((p = strchr(s, '%')) != NULL) {
- *p = 0;
+ *p = 0;
p++;
+ password = p;
+ } else {
+ password = "";
}
name = s;
- password = p;
wbc_status = wbcAuthenticateUser(name, password);
- d_printf("plaintext password authentication %s\n",
+ d_printf("plaintext password authentication %s\n",
WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
#if 0
if (response.data.auth.nt_status)
d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
+ response.data.auth.nt_status_string,
response.data.auth.nt_status,
response.data.auth.error_string);
#endif
SAFE_FREE(s);
- return WBC_ERROR_IS_OK(wbc_status);
+ return WBC_ERROR_IS_OK(wbc_status);
}
/* Authenticate a user with a challenge/response */
static bool wbinfo_auth_crap(char *username)
{
- struct winbindd_request request;
- struct winbindd_response response;
- NSS_STATUS result;
- fstring name_user;
- fstring name_domain;
- fstring pass;
- char *p;
-
- /* Send off request */
-
- ZERO_STRUCT(request);
- ZERO_STRUCT(response);
+ wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+ struct wbcAuthUserParams params;
+ struct wbcAuthUserInfo *info = NULL;
+ struct wbcAuthErrorInfo *err = NULL;
+ DATA_BLOB lm = data_blob_null;
+ DATA_BLOB nt = data_blob_null;
+ fstring name_user;
+ fstring name_domain;
+ fstring pass;
+ char *p;
- p = strchr(username, '%');
+ p = strchr(username, '%');
- if (p) {
- *p = 0;
- fstrcpy(pass, p + 1);
+ if (p) {
+ *p = 0;
+ fstrcpy(pass, p + 1);
}
parse_wbinfo_domain_user(username, name_domain, name_user);
- request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
+ params.account_name = name_user;
+ params.domain_name = name_domain;
+ params.workstation_name = NULL;
- fstrcpy(request.data.auth_crap.user, name_user);
+ params.flags = 0;
+ params.parameter_control= WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT |
+ WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;
- fstrcpy(request.data.auth_crap.domain,
- name_domain);
+ params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
+
+ generate_random_buffer(params.password.response.challenge, 8);
- generate_random_buffer(request.data.auth_crap.chal, 8);
-
if (lp_client_ntlmv2_auth()) {
DATA_BLOB server_chal;
- DATA_BLOB names_blob;
+ DATA_BLOB names_blob;
- DATA_BLOB lm_response;
- DATA_BLOB nt_response;
+ server_chal = data_blob(params.password.response.challenge, 8);
- server_chal = data_blob(request.data.auth_crap.chal, 8);
-
/* Pretend this is a login to 'us', for blob purposes */
names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
-
- if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
+
+ if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
&names_blob,
- &lm_response, &nt_response, NULL)) {
+ &lm, &nt, NULL)) {
data_blob_free(&names_blob);
data_blob_free(&server_chal);
- return False;
+ return false;
}
data_blob_free(&names_blob);
data_blob_free(&server_chal);
- memcpy(request.data.auth_crap.nt_resp, nt_response.data,
- MIN(nt_response.length,
- sizeof(request.data.auth_crap.nt_resp)));
- request.data.auth_crap.nt_resp_len = nt_response.length;
-
- memcpy(request.data.auth_crap.lm_resp, lm_response.data,
- MIN(lm_response.length,
- sizeof(request.data.auth_crap.lm_resp)));
- request.data.auth_crap.lm_resp_len = lm_response.length;
-
- data_blob_free(&nt_response);
- data_blob_free(&lm_response);
-
} else {
- if (lp_client_lanman_auth()
- && SMBencrypt(pass, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.lm_resp)) {
- request.data.auth_crap.lm_resp_len = 24;
- } else {
- request.data.auth_crap.lm_resp_len = 0;
+ if (lp_client_lanman_auth()) {
+ bool ok;
+ lm = data_blob(NULL, 24);
+ ok = SMBencrypt(pass, params.password.response.challenge,
+ lm.data);
+ if (!ok) {
+ data_blob_free(&lm);
+ }
}
- SMBNTencrypt(pass, request.data.auth_crap.chal,
- (uchar *)request.data.auth_crap.nt_resp);
-
- request.data.auth_crap.nt_resp_len = 24;
+ nt = data_blob(NULL, 24);
+ SMBNTencrypt(pass, params.password.response.challenge,
+ nt.data);
}
- result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+ params.password.response.nt_length = nt.length;
+ params.password.response.nt_data = nt.data;
+ params.password.response.lm_length = lm.length;
+ params.password.response.lm_data = lm.data;
+
+ wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
/* Display response */
- d_printf("challenge/response password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+ d_printf("challenge/response password authentication %s\n",
+ WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed");
- if (response.data.auth.nt_status)
+ if (wbc_status == WBC_ERR_AUTH_ERROR) {
d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
- response.data.auth.nt_status,
- response.data.auth.error_string);
+ err->nt_string,
+ err->nt_status,
+ err->display_string);
+ wbcFreeMemory(err);
+ } else if (WBC_ERROR_IS_OK(wbc_status)) {
+ wbcFreeMemory(info);
+ }
+
+ data_blob_free(&nt);
+ data_blob_free(&lm);
- return result == NSS_STATUS_SUCCESS;
+ return WBC_ERROR_IS_OK(wbc_status);
}
/* Authenticate a user with a plaintext password and set a token */
@@ -1004,23 +1004,23 @@ static bool wbinfo_klog(char *username)
{
struct winbindd_request request;
struct winbindd_response response;
- NSS_STATUS result;
- char *p;
+ NSS_STATUS result;
+ char *p;
/* Send off request */
ZERO_STRUCT(request);
ZERO_STRUCT(response);
- p = strchr(username, '%');
+ p = strchr(username, '%');
- if (p) {
- *p = 0;
- fstrcpy(request.data.auth.user, username);
- fstrcpy(request.data.auth.pass, p + 1);
- *p = '%';
- } else {
- fstrcpy(request.data.auth.user, username);
+ if (p) {
+ *p = 0;
+ fstrcpy(request.data.auth.user, username);
+ fstrcpy(request.data.auth.pass, p + 1);
+ *p = '%';
+ } else {
+ fstrcpy(request.data.auth.user, username);
fstrcpy(request.data.auth.pass, getpass("Password: "));
}
@@ -1030,30 +1030,30 @@ static bool wbinfo_klog(char *username)
/* Display response */
- d_printf("plaintext password authentication %s\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+ d_printf("plaintext password authentication %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
if (response.data.auth.nt_status)
d_fprintf(stderr, "error code was %s (0x%x)\nerror messsage was: %s\n",
- response.data.auth.nt_status_string,
+ response.data.auth.nt_status_string,
response.data.auth.nt_status,
response.data.auth.error_string);
if (result != NSS_STATUS_SUCCESS)
- return False;
+ return false;
if (response.extra_data.data == NULL) {
d_fprintf(stderr, "Did not get token data\n");
- return False;
+ return false;
}
if (!afs_settoken_str((char *)response.extra_data.data)) {
d_fprintf(stderr, "Could not set token\n");
- return False;
+ return false;
}
d_printf("Successfully created AFS token\n");
- return True;
+ return true;
}
/* Print domain users */
@@ -1081,12 +1081,12 @@ static bool print_domain_users(const char *domain)
if (winbindd_request_response(WINBINDD_LIST_USERS, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Look through extra data */
if (!response.extra_data.data)
- return False;
+ return false;
extra_data = (const char *)response.extra_data.data;
@@ -1097,7 +1097,7 @@ static bool print_domain_users(const char *domain)
SAFE_FREE(response.extra_data.data);
- return True;
+ return true;
}
/* Print domain groups */
@@ -1122,12 +1122,12 @@ static bool print_domain_groups(const char *domain)
if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) !=
NSS_STATUS_SUCCESS)
- return False;
+ return false;
/* Look through extra data */
if (!response.extra_data.data)
- return False;
+ return false;
extra_data = (const char *)response.extra_data.data;
@@ -1138,7 +1138,7 @@ static bool print_domain_groups(const char *domain)
SAFE_FREE(response.extra_data.data);
- return True;
+ return true;
}
/* Set the authorised user for winbindd access in secrets.tdb */
@@ -1161,7 +1161,7 @@ static bool wbinfo_set_auth_user(char *username)
} else {
char *thepass = getpass("Password: ");
if (thepass) {
- password = thepass;
+ password = thepass;
} else
password = "";
}
@@ -1175,7 +1175,7 @@ static bool wbinfo_set_auth_user(char *username)
if (!secrets_store(SECRETS_AUTH_USER, user,
strlen(user) + 1)) {
d_fprintf(stderr, "error storing username\n");
- return False;
+ return false;
}
/* We always have a domain name added by the
@@ -1184,7 +1184,7 @@ static bool wbinfo_set_auth_user(char *username)
if (!secrets_store(SECRETS_AUTH_DOMAIN, domain,
strlen(domain) + 1)) {
d_fprintf(stderr, "error storing domain name\n");
- return False;
+ return false;
}
} else {
@@ -1197,13 +1197,13 @@ static bool wbinfo_set_auth_user(char *username)
if (!secrets_store(SECRETS_AUTH_PASSWORD, password,
strlen(password) + 1)) {
d_fprintf(stderr, "error storing password\n");
- return False;
+ return false;
}
} else
secrets_delete(SECRETS_AUTH_PASSWORD);
- return True;
+ return true;
}
static void wbinfo_get_auth_user(void)
@@ -1211,7 +1211,7 @@ static void wbinfo_get_auth_user(void)
char *user, *domain, *password;
/* Lift data from secrets file */
-
+
secrets_fetch_ipc_userpass(&user, &domain, &password);
if ((!user || !*user) && (!domain || !*domain ) && (!password || !*password)){
@@ -1241,10 +1241,10 @@ static bool wbinfo_ping(void)
/* Display response */
- d_printf("Ping to winbindd %s on fd %d\n",
- (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd);
+ d_printf("Ping to winbindd %s on fd %d\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd);
- return result == NSS_STATUS_SUCCESS;
+ return result == NSS_STATUS_SUCCESS;
}
/* Main program */
@@ -1270,7 +1270,7 @@ enum {
int main(int argc, char **argv, char **envp)
{
int opt;
- TALLOC_CTX *frame = talloc_stackframe();
+ TALLOC_CTX *frame = talloc_stackframe();
poptContext pc;
static char *string_arg;
static char *opt_domain_name;
@@ -1280,7 +1280,7 @@ int main(int argc, char **argv, char **envp)
struct poptOption long_options[] = {
POPT_AUTOHELP
- /* longName, shortName, argInfo, argPtr, value, descrip,
+ /* longName, shortName, argInfo, argPtr, value, descrip,
argDesc */
{ "domain-users", 'u', POPT_ARG_NONE, 0, 'u', "Lists all domain users", "domain"},
@@ -1354,7 +1354,7 @@ int main(int argc, char **argv, char **envp)
poptFreeContext(pc);
- if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) {
+ if (!lp_load(get_dyn_CONFIGFILE(), true, false, false, true)) {
d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
get_dyn_CONFIGFILE(), strerror(errno));
exit(1);
@@ -1458,7 +1458,7 @@ int main(int argc, char **argv, char **envp)
}
break;
case 'm':
- if (!wbinfo_list_domains(False)) {
+ if (!wbinfo_list_domains(false)) {
d_fprintf(stderr, "Could not list trusted domains\n");
goto done;
}
@@ -1518,18 +1518,18 @@ int main(int argc, char **argv, char **envp)
}
break;
case 'a': {
- bool got_error = False;
+ bool got_error = false;
if (!wbinfo_auth(string_arg)) {
d_fprintf(stderr, "Could not authenticate user %s with "
"plaintext password\n", string_arg);
- got_error = True;
+ got_error = true;
}
if (!wbinfo_auth_crap(string_arg)) {
d_fprintf(stderr, "Could not authenticate user %s with "
"challenge/response\n", string_arg);
- got_error = True;
+ got_error = true;
}
if (got_error)
@@ -1580,7 +1580,7 @@ int main(int argc, char **argv, char **envp)
}
break;
case OPT_SEPARATOR: {
- const char sep = winbind_separator_int(True);
+ const char sep = winbind_separator_int(true);
if ( !sep ) {
goto done;
}
@@ -1588,7 +1588,7 @@ int main(int argc, char **argv, char **envp)
break;
}
case OPT_LIST_ALL_DOMAINS:
- if (!wbinfo_list_domains(True)) {
+ if (!wbinfo_list_domains(true)) {
goto done;
}
break;
diff --git a/source3/nsswitch/winbind_client.h b/source3/nsswitch/winbind_client.h
index 2a3956e1fd..757f5869e9 100644
--- a/source3/nsswitch/winbind_client.h
+++ b/source3/nsswitch/winbind_client.h
@@ -14,9 +14,14 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
struct winbindd_response *response);
int winbindd_read_reply(struct winbindd_response *response);
-bool winbind_env_set(void);
-bool winbind_off(void);
-bool winbind_on(void);
+#define winbind_env_set() \
+ (strcmp(getenv(WINBINDD_DONT_ENV)?getenv(WINBINDD_DONT_ENV):"0","1") == 0)
+
+#define winbind_off() \
+ (setenv(WINBINDD_DONT_ENV, "1", 1) == 0)
+
+#define winbind_on() \
+ (setenv(WINBINDD_DONT_ENV, "0", 1) == 0)
int winbind_write_sock(void *buffer, int count, int recursing, int need_priv);
int winbind_read_sock(void *buffer, int count);
diff --git a/source3/nsswitch/winbind_krb5_locator.c b/source3/nsswitch/winbind_krb5_locator.c
index eef57ca2c0..33a68f0cdc 100644
--- a/source3/nsswitch/winbind_krb5_locator.c
+++ b/source3/nsswitch/winbind_krb5_locator.c
@@ -90,7 +90,7 @@ static const char *family_name(int family)
return "AF_UNSPEC";
case AF_INET:
return "AF_INET";
-#if defined(HAVE_IPv6)
+#if defined(HAVE_IPV6)
case AF_INET6:
return "AF_INET6";
#endif
@@ -137,9 +137,9 @@ static int smb_krb5_locator_lookup_sanity_check(enum locate_service_type svc,
case AF_UNSPEC:
case AF_INET:
break;
-#if defined(HAVE_IPv6)
- case AF_INET6: /* not yet */
- return KRB5_PLUGIN_NO_HANDLE;
+#if defined(HAVE_IPV6)
+ case AF_INET6:
+ break;
#endif
default:
return EINVAL;
diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h
index 12ca1e55c8..e81813c77b 100644
--- a/source3/nsswitch/winbind_struct_protocol.h
+++ b/source3/nsswitch/winbind_struct_protocol.h
@@ -431,6 +431,7 @@ struct winbindd_response {
fstring logon_srv;
fstring logon_dom;
} info3;
+ fstring unix_username;
} auth;
struct {
fstring name;
diff --git a/source3/nsswitch/wins.c b/source3/nsswitch/wins.c
index c822fc78b9..35649dfda2 100644
--- a/source3/nsswitch/wins.c
+++ b/source3/nsswitch/wins.c
@@ -147,7 +147,7 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
{
int fd;
- struct in_addr ip;
+ struct sockaddr_storage ss;
struct nmb_name nname;
NODE_STATUS_STRUCT *status;
@@ -160,8 +160,10 @@ static NODE_STATUS_STRUCT *lookup_byaddr_backend(char *addr, int *count)
return NULL;
make_nmb_name(&nname, "*", 0);
- (void)interpret_addr2(&ip,addr);
- status = node_status_query(fd,&nname,ip, count, NULL);
+ if (!interpret_string_addr(&ss, addr, AI_NUMERICHOST)) {
+ return NULL;
+ }
+ status = node_status_query(fd, &nname, &ss, count, NULL);
close(fd);
return status;