summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-09-08 20:38:52 +0000
committerJeremy Allison <jra@samba.org>2001-09-08 20:38:52 +0000
commit306590aa061bb869ff5d8550d5b3e069c8231b8e (patch)
tree8ca03b97aabdd0f3aa33c45878ef4f74dc41deb6
parentcc728c9226fa535f6a5f8ad3b2852250f87715eb (diff)
downloadsamba-306590aa061bb869ff5d8550d5b3e069c8231b8e.tar.gz
samba-306590aa061bb869ff5d8550d5b3e069c8231b8e.tar.xz
samba-306590aa061bb869ff5d8550d5b3e069c8231b8e.zip
Fix Solaris winbindd bugs confusing winbindd errors with nsswitch errors.
Added wbinfo backport from JEAD (CRAP auth added). Jeremy.
-rw-r--r--source/Makefile.in2
-rw-r--r--source/include/includes.h35
-rw-r--r--source/nsswitch/wbinfo.c170
-rw-r--r--source/nsswitch/winbind_nss_config.h38
-rw-r--r--source/nsswitch/winbindd_idmap.c4
-rw-r--r--source/nsswitch/winbindd_nss.h9
-rw-r--r--source/nsswitch/winbindd_user.c5
7 files changed, 157 insertions, 106 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index e37692cfc1a..e190d8d270e 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -379,7 +379,7 @@ WINBINDD_OBJ = \
$(GROUPDB_OBJ) $(PROFILE_OBJ) \
$(NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ)
-WBINFO_OBJ = nsswitch/wbinfo.o
+WBINFO_OBJ = nsswitch/wbinfo.o libsmb/smbencrypt.o libsmb/smbdes.o
WINBIND_NSS_OBJ = nsswitch/winbind_nss.o nsswitch/wb_common.o
diff --git a/source/include/includes.h b/source/include/includes.h
index 9566c7a42da..3d4dca1c33c 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -701,40 +701,7 @@ typedef struct smb_wpasswd {
#define UNI_XDIGIT 0x8
#define UNI_SPACE 0x10
-#ifdef HAVE_NSS_COMMON_H
-
-/* Sun Solaris */
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#elif HAVE_NSS_H
-
-/* GNU */
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#else /* Nothing's defined. Neither gnu nor sun */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS,
- NSS_STATUS_NOTFOUND,
- NSS_STATUS_UNAVAIL,
- NSS_STATUS_TRYAGAIN
-} NSS_STATUS;
-
-#endif
+#include "nsswitch/nss.h"
/***** automatically generated prototypes *****/
#include "proto.h"
diff --git a/source/nsswitch/wbinfo.c b/source/nsswitch/wbinfo.c
index 9d3568417f4..d29b144147d 100644
--- a/source/nsswitch/wbinfo.c
+++ b/source/nsswitch/wbinfo.c
@@ -27,8 +27,9 @@
/* Prototypes from common.h */
-int winbindd_request(int req_type, struct winbindd_request *request,
- struct winbindd_response *response);
+NSS_STATUS winbindd_request(int req_type,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
/* List groups a user is a member of */
@@ -36,7 +37,8 @@ static BOOL wbinfo_get_usergroups(char *user)
{
struct winbindd_request request;
struct winbindd_response response;
- int result, i;
+ NSS_STATUS result;
+ int i;
ZERO_STRUCT(response);
@@ -68,8 +70,8 @@ static BOOL wbinfo_list_domains(void)
/* Send request */
- if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_TRUSTDOM, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -125,8 +127,8 @@ static BOOL wbinfo_uid_to_sid(uid_t uid)
/* Send request */
request.data.uid = uid;
- if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -150,8 +152,8 @@ static BOOL wbinfo_gid_to_sid(gid_t gid)
/* Send request */
request.data.gid = gid;
- if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_GID_TO_SID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -175,8 +177,8 @@ static BOOL wbinfo_sid_to_uid(char *sid)
/* Send request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_SID_TO_UID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -198,8 +200,8 @@ static BOOL wbinfo_sid_to_gid(char *sid)
/* Send request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_SID_TO_GID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -223,8 +225,8 @@ static BOOL wbinfo_lookupsid(char *sid)
/* Send off request */
fstrcpy(request.data.sid, sid);
- if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LOOKUPSID, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -248,8 +250,8 @@ static BOOL wbinfo_lookupname(char *name)
ZERO_STRUCT(response);
fstrcpy(request.data.name, name);
- if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -260,6 +262,85 @@ static BOOL wbinfo_lookupname(char *name)
return True;
}
+/* Authenticate a user with a plaintext password */
+
+static BOOL wbinfo_auth(char *username)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ NSS_STATUS result;
+ char *p;
+
+ /* Send off request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ 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);
+
+ result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
+
+ /* Display response */
+
+ printf("plaintext password authentication %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+
+ return result == NSS_STATUS_SUCCESS;
+}
+
+/* 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 pass;
+ char *p;
+
+ /* Send off request */
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ p = strchr(username, '%');
+
+ if (p) {
+ *p = 0;
+ fstrcpy(request.data.auth_crap.user, username);
+ fstrcpy(pass, p + 1);
+ *p = '%';
+ } else
+ fstrcpy(request.data.auth_crap.user, username);
+
+ generate_random_buffer(request.data.auth_crap.chal, 8, False);
+
+ SMBencrypt((uchar *)pass, request.data.auth_crap.chal,
+ (uchar *)request.data.auth_crap.lm_resp);
+ SMBNTencrypt((uchar *)pass, request.data.auth_crap.chal,
+ (uchar *)request.data.auth_crap.nt_resp);
+
+ request.data.auth_crap.lm_resp_len = 24;
+ request.data.auth_crap.nt_resp_len = 24;
+
+ result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+
+ /* Display response */
+
+ printf("challenge/response password authentication %s\n",
+ (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
+
+ return result == NSS_STATUS_SUCCESS;
+}
+
/* Print domain users */
static BOOL print_domain_users(void)
@@ -271,8 +352,8 @@ static BOOL print_domain_users(void)
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_USERS, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -299,8 +380,8 @@ static BOOL print_domain_groups(void)
ZERO_STRUCT(response);
- if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) ==
- WINBINDD_ERROR) {
+ if (winbindd_request(WINBINDD_LIST_GROUPS, NULL, &response) !=
+ NSS_STATUS_SUCCESS) {
return False;
}
@@ -322,18 +403,20 @@ static BOOL print_domain_groups(void)
static void usage(void)
{
- printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm\n");
- printf("\t-u\tlists all domain users\n");
- printf("\t-g\tlists all domain groups\n");
- printf("\t-n name\tconverts name to sid\n");
- printf("\t-s sid\tconverts sid to name\n");
- printf("\t-U uid\tconverts uid to sid\n");
- printf("\t-G gid\tconverts gid to sid\n");
- printf("\t-S sid\tconverts sid to uid\n");
- printf("\t-Y sid\tconverts sid to gid\n");
- printf("\t-t\tcheck shared secret\n");
- printf("\t-m\tlist trusted domains\n");
- printf("\t-r user\tget user groups\n");
+ printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
+ "| -a user%%password\n");
+ printf("\t-u\t\t\tlists all domain users\n");
+ printf("\t-g\t\t\tlists all domain groups\n");
+ printf("\t-n name\t\t\tconverts name to sid\n");
+ printf("\t-s sid\t\t\tconverts sid to name\n");
+ printf("\t-U uid\t\t\tconverts uid to sid\n");
+ printf("\t-G gid\t\t\tconverts gid to sid\n");
+ printf("\t-S sid\t\t\tconverts sid to uid\n");
+ printf("\t-Y sid\t\t\tconverts sid to gid\n");
+ printf("\t-t\t\t\tcheck shared secret\n");
+ printf("\t-m\t\t\tlist trusted domains\n");
+ printf("\t-r user\t\t\tget user groups\n");
+ printf("\t-a user%%password\tauthenticate user\n");
}
/* Main program */
@@ -371,7 +454,7 @@ int main(int argc, char **argv)
return 1;
}
- while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:")) != EOF) {
+ while ((opt = getopt(argc, argv, "ugs:n:U:G:S:Y:tmr:a:")) != EOF) {
switch (opt) {
case 'u':
if (!print_domain_users()) {
@@ -444,7 +527,26 @@ int main(int argc, char **argv)
return 1;
}
break;
+ case 'a': {
+ BOOL got_error = False;
+
+ if (!wbinfo_auth(optarg)) {
+ printf("Could not authenticate user %s with "
+ "plaintext password\n", optarg);
+ got_error = True;
+ }
+
+ if (!wbinfo_auth_crap(optarg)) {
+ printf("Could not authenticate user %s with "
+ "challenge/response\n", optarg);
+ got_error = True;
+ }
+
+ if (got_error)
+ return 1;
+ break;
+ }
/* Invalid option */
default:
diff --git a/source/nsswitch/winbind_nss_config.h b/source/nsswitch/winbind_nss_config.h
index 4902f6ec5c4..88561ee8084 100644
--- a/source/nsswitch/winbind_nss_config.h
+++ b/source/nsswitch/winbind_nss_config.h
@@ -55,43 +55,15 @@
#include <grp.h>
#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
-
-#ifdef HAVE_NSS_COMMON_H
-/* Sun Solaris */
-
-#include <nss_common.h>
-#include <nss_dbdefs.h>
-#include <nsswitch.h>
-
-typedef nss_status_t NSS_STATUS;
-
-#define NSS_STATUS_SUCCESS NSS_SUCCESS
-#define NSS_STATUS_NOTFOUND NSS_NOTFOUND
-#define NSS_STATUS_UNAVAIL NSS_UNAVAIL
-#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN
-
-#elif HAVE_NSS_H
-/* GNU */
-
-#include <nss.h>
-
-typedef enum nss_status NSS_STATUS;
-
-#else /* Nothing's defined. Neither gnu nor sun */
-
-typedef enum
-{
- NSS_STATUS_SUCCESS,
- NSS_STATUS_NOTFOUND,
- NSS_STATUS_UNAVAIL,
- NSS_STATUS_TRYAGAIN
-} NSS_STATUS;
-
-#endif
+#include "nsswitch/nss.h"
/* Declarations for functions in winbind_nss.c
needed in winbind_nss_solaris.c (solaris wrapper to nss) */
diff --git a/source/nsswitch/winbindd_idmap.c b/source/nsswitch/winbindd_idmap.c
index 73d24f19f66..5f667a621bc 100644
--- a/source/nsswitch/winbindd_idmap.c
+++ b/source/nsswitch/winbindd_idmap.c
@@ -34,7 +34,7 @@ static TDB_CONTEXT *idmap_tdb;
/* Allocate either a user or group id from the pool */
-static BOOL allocate_id(int *id, BOOL isgroup)
+static BOOL allocate_id(uid_t *id, BOOL isgroup)
{
int hwm;
@@ -68,7 +68,7 @@ static BOOL allocate_id(int *id, BOOL isgroup)
/* Get an id from a rid */
-static BOOL get_id_from_rid(char *domain_name, uint32 rid, int *id,
+static BOOL get_id_from_rid(char *domain_name, uint32 rid, uid_t *id,
BOOL isgroup)
{
TDB_DATA data, key;
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index aedbaaf1fd9..ed7a0d4a28b 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -55,6 +55,7 @@ enum winbindd_cmd {
/* PAM authenticate and password change */
WINBINDD_PAM_AUTH,
+ WINBINDD_PAM_AUTH_CRAP,
WINBINDD_PAM_CHAUTHTOK,
/* List various things */
@@ -100,6 +101,14 @@ struct winbindd_request {
fstring pass;
} auth; /* pam_winbind auth module */
struct {
+ unsigned char chal[8];
+ fstring user;
+ fstring lm_resp;
+ uint16 lm_resp_len;
+ fstring nt_resp;
+ uint16 nt_resp_len;
+ } auth_crap;
+ struct {
fstring user;
fstring oldpass;
fstring newpass;
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index 3d76ec90460..15eb6054f19 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -94,12 +94,13 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name,
enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
*state)
{
- uint32 name_type, user_rid, group_rid;
+ uint32 user_rid, group_rid;
SAM_USERINFO_CTR *user_info;
DOM_SID user_sid;
fstring name_domain, name_user, name, gecos_name;
struct winbindd_domain *domain;
-
+ enum SID_NAME_USE name_type;
+
DEBUG(3, ("[%5d]: getpwnam %s\n", state->pid,
state->request.data.username));