diff options
author | Jeremy Allison <jra@samba.org> | 2001-09-08 20:38:52 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-09-08 20:38:52 +0000 |
commit | 306590aa061bb869ff5d8550d5b3e069c8231b8e (patch) | |
tree | 8ca03b97aabdd0f3aa33c45878ef4f74dc41deb6 | |
parent | cc728c9226fa535f6a5f8ad3b2852250f87715eb (diff) | |
download | samba-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.in | 2 | ||||
-rw-r--r-- | source/include/includes.h | 35 | ||||
-rw-r--r-- | source/nsswitch/wbinfo.c | 170 | ||||
-rw-r--r-- | source/nsswitch/winbind_nss_config.h | 38 | ||||
-rw-r--r-- | source/nsswitch/winbindd_idmap.c | 4 | ||||
-rw-r--r-- | source/nsswitch/winbindd_nss.h | 9 | ||||
-rw-r--r-- | source/nsswitch/winbindd_user.c | 5 |
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)); |