From 0f7efe998683c81a1f33f59871e1fad72df3d9be Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 9 Jan 2010 20:20:36 +0100 Subject: [PATCH 01/14] s3: Add wbinfo --ccache-save With this command you can give winbind your password for later use by the automatic ntlm_auth --- nsswitch/libwbclient/wbc_pam.c | 18 +++++++ nsswitch/libwbclient/wbclient.h | 10 ++++ nsswitch/wbinfo.c | 46 ++++++++++++++++++ nsswitch/winbind_struct_protocol.h | 9 +++- source3/winbindd/winbindd.c | 1 + source3/winbindd/winbindd_ccache_access.c | 72 +++++++++++++++++++++++++++++ source3/winbindd/winbindd_domain.c | 4 ++ source3/winbindd/winbindd_proto.h | 3 + 8 files changed, 162 insertions(+), 1 deletions(-) diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 00863a0..27d5be6 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -1120,3 +1120,21 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, { return WBC_ERR_NOT_IMPLEMENTED; } + +/* Authenticate a user with cached credentials */ +wbcErr wbcCredentialSave(const char *user, const char *password) +{ + struct winbindd_request request; + struct winbindd_response response; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + strncpy(request.data.ccache_save.user, user, + sizeof(request.data.ccache_save.user)-1); + strncpy(request.data.ccache_save.pass, password, + sizeof(request.data.ccache_save.pass)-1); + request.data.ccache_save.uid = getuid(); + + return wbcRequestResponse(WINBINDD_CCACHE_SAVE, &request, &response); +} diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h index 8bbbfbc..ac20690 100644 --- a/nsswitch/libwbclient/wbclient.h +++ b/nsswitch/libwbclient/wbclient.h @@ -1153,6 +1153,16 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error); +/** + * @brief Save a password with winbind for doing wbcCredentialCache() later + * + * @param *user Username + * @param *password Password + * + * @return #wbcErr + **/ +wbcErr wbcCredentialSave(const char *user, const char *password); + /********************************************************** * Resolve functions **********************************************************/ diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c index 45d8684..a43ce8f 100644 --- a/nsswitch/wbinfo.c +++ b/nsswitch/wbinfo.c @@ -1530,6 +1530,43 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman) return WBC_ERROR_IS_OK(wbc_status); } +/* Save creds with winbind */ + +static bool wbinfo_ccache_save(char *username) +{ + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + char *s = NULL; + char *p = NULL; + char *password = NULL; + char *name = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + s = talloc_strdup(frame, username); + if (s == NULL) { + return false; + } + + p = strchr(s, '%'); + if (p != NULL) { + *p = 0; + p++; + password = talloc_strdup(frame, p); + } else { + password = wbinfo_prompt_pass(frame, NULL, username); + } + + name = s; + + wbc_status = wbcCredentialSave(name, password); + + d_printf("saving creds %s\n", + WBC_ERROR_IS_OK(wbc_status) ? "succeeded" : "failed"); + + TALLOC_FREE(frame); + + return WBC_ERROR_IS_OK(wbc_status); +} + #ifdef WITH_FAKE_KASERVER /* Authenticate a user with a plaintext password and set a token */ @@ -1736,6 +1773,7 @@ enum { OPT_ONLINESTATUS, OPT_CHANGE_USER_PASSWORD, OPT_PING_DC, + OPT_CCACHE_SAVE, OPT_SID_TO_FULLNAME, OPT_NTLMV2, OPT_LANMAN @@ -1805,6 +1843,9 @@ int main(int argc, char **argv, char **envp) { "user-sids", 0, POPT_ARG_STRING, &string_arg, OPT_USERSIDS, "Get user group sids for user SID", "SID" }, { "authenticate", 'a', POPT_ARG_STRING, &string_arg, 'a', "authenticate user", "user%password" }, { "set-auth-user", 0, POPT_ARG_STRING, &string_arg, OPT_SET_AUTH_USER, "Store user and password used by winbindd (root only)", "user%password" }, + { "ccache-save", 0, POPT_ARG_STRING, &string_arg, + OPT_CCACHE_SAVE, "Store user and password for ccache " + "operation", "user%password" }, { "getdcname", 0, POPT_ARG_STRING, &string_arg, OPT_GETDCNAME, "Get a DC name for a foreign domain", "domainname" }, { "dsgetdcname", 0, POPT_ARG_STRING, &string_arg, OPT_DSGETDCNAME, "Find a DC for a domain", "domainname" }, @@ -2189,6 +2230,11 @@ int main(int argc, char **argv, char **envp) wbinfo_get_auth_user(); goto done; break; + case OPT_CCACHE_SAVE: + if (!wbinfo_ccache_save(string_arg)) { + goto done; + } + break; case OPT_GETDCNAME: if (!wbinfo_getdcname(string_arg)) { goto done; diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 4d27d52..7790155 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -48,8 +48,9 @@ typedef char fstring[FSTRING_LEN]; * 21: added WINBINDD_GETPWSID * added WINBINDD_GETSIDALIASES * 22: added WINBINDD_PING_DC + * 23: added WINBINDD_CCACHE_SAVE */ -#define WINBIND_INTERFACE_VERSION 22 +#define WINBIND_INTERFACE_VERSION 23 /* Have to deal with time_t being 4 or 8 bytes due to structure alignment. On a 64bit Linux box, we have to support a constant structure size @@ -177,6 +178,7 @@ enum winbindd_cmd { /* Complete the challenge phase of the NTLM authentication protocol using cached password. */ WINBINDD_CCACHE_NTLMAUTH, + WINBINDD_CCACHE_SAVE, WINBINDD_NUM_CMDS }; @@ -335,6 +337,11 @@ struct winbindd_request { uint32_t challenge_blob_len; } ccache_ntlm_auth; struct { + uid_t uid; + fstring user; + fstring pass; + } ccache_save; + struct { fstring domain_name; fstring domain_guid; fstring site_name; diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index f6f4a8f..c0b42b8 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -451,6 +451,7 @@ static struct winbindd_dispatch_table { /* Credential cache access */ { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" }, + { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" }, /* WINS functions */ diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 508bda4..7435c26 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -283,3 +283,75 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma process_result: return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } + +void winbindd_ccache_save(struct winbindd_cli_state *state) +{ + struct winbindd_domain *domain; + fstring name_domain, name_user; + + /* Ensure null termination */ + state->request->data.ccache_save.user[ + sizeof(state->request->data.ccache_save.user)-1]='\0'; + state->request->data.ccache_save.pass[ + sizeof(state->request->data.ccache_save.pass)-1]='\0'; + + DEBUG(3, ("[%5lu]: save passord of user %s\n", + (unsigned long)state->pid, + state->request->data.ccache_save.user)); + + /* Parse domain and username */ + + if (!canonicalize_username(state->request->data.ccache_ntlm_auth.user, + name_domain, name_user)) { + DEBUG(5,("winbindd_ccache_save: cannot parse domain and user " + "from name [%s]\n", + state->request->data.ccache_save.user)); + request_error(state); + return; + } + + domain = find_auth_domain(state->request->flags, name_domain); + + if (domain == NULL) { + DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n", + name_domain)); + request_error(state); + return; + } + + if (!check_client_uid(state, state->request->data.ccache_save.uid)) { + request_error(state); + return; + } + + sendto_domain(state, domain); +} + +enum winbindd_result winbindd_dual_ccache_save( + struct winbindd_domain *domain, struct winbindd_cli_state *state) +{ + NTSTATUS status = NT_STATUS_NOT_SUPPORTED; + + /* Ensure null termination */ + state->request->data.ccache_save.user[ + sizeof(state->request->data.ccache_save.user)-1]='\0'; + state->request->data.ccache_save.pass[ + sizeof(state->request->data.ccache_save.pass)-1]='\0'; + + DEBUG(3, ("winbindd_dual_ccache_save: [%5lu]: save password of user " + "%s\n", (unsigned long)state->pid, + state->request->data.ccache_save.user)); + + status = winbindd_add_memory_creds( + state->request->data.ccache_save.user, + state->request->data.ccache_save.uid, + state->request->data.ccache_save.pass); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("winbindd_add_memory_creds failed %s\n", + nt_errstr(status))); + return WINBINDD_ERROR; + } + + return WINBINDD_OK; +} diff --git a/source3/winbindd/winbindd_domain.c b/source3/winbindd/winbindd_domain.c index 45da57e..2cb6e31 100644 --- a/source3/winbindd/winbindd_domain.c +++ b/source3/winbindd/winbindd_domain.c @@ -67,6 +67,10 @@ static const struct winbindd_child_dispatch_table domain_dispatch_table[] = { .struct_cmd = WINBINDD_CCACHE_NTLMAUTH, .struct_fn = winbindd_dual_ccache_ntlm_auth, },{ + .name = "CCACHE_SAVE", + .struct_cmd = WINBINDD_CCACHE_SAVE, + .struct_fn = winbindd_dual_ccache_save, + },{ .name = "NDRCMD", .struct_cmd = WINBINDD_DUAL_NDRCMD, .struct_fn = winbindd_dual_ndrcmd, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 263e326..62fbc8e 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -180,6 +180,9 @@ void wcache_store_ndr(struct winbindd_domain *domain, uint32_t opnum, void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state); enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *domain, struct winbindd_cli_state *state); +void winbindd_ccache_save(struct winbindd_cli_state *state); +enum winbindd_result winbindd_dual_ccache_save( + struct winbindd_domain *domain, struct winbindd_cli_state *state); /* The following definitions come from winbindd/winbindd_cm.c */ -- 1.6.5.7 From ed016b5c1f33f52d911b3bef6c84e241883ca24a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 16:41:30 +0100 Subject: [PATCH 02/14] s3: Add the session key to the ccache_ntlm_auth response --- nsswitch/winbind_struct_protocol.h | 4 +++- source3/winbindd/winbindd_ccache_access.c | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/nsswitch/winbind_struct_protocol.h b/nsswitch/winbind_struct_protocol.h index 7790155..2e0751f 100644 --- a/nsswitch/winbind_struct_protocol.h +++ b/nsswitch/winbind_struct_protocol.h @@ -48,7 +48,8 @@ typedef char fstring[FSTRING_LEN]; * 21: added WINBINDD_GETPWSID * added WINBINDD_GETSIDALIASES * 22: added WINBINDD_PING_DC - * 23: added WINBINDD_CCACHE_SAVE + * 23: added session_key to ccache_ntlm_auth response + * added WINBINDD_CCACHE_SAVE */ #define WINBIND_INTERFACE_VERSION 23 @@ -485,6 +486,7 @@ struct winbindd_response { uint32_t group_rid; } user_info; struct { + uint8_t session_key[16]; uint32_t auth_blob_len; /* blob in extra_data */ } ccache_ntlm_auth; struct { diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c index 7435c26..b36b067 100644 --- a/source3/winbindd/winbindd_ccache_access.c +++ b/source3/winbindd/winbindd_ccache_access.c @@ -46,7 +46,8 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, const unsigned char nt_hash[NT_HASH_LEN], const DATA_BLOB initial_msg, const DATA_BLOB challenge_msg, - DATA_BLOB *auth_msg) + DATA_BLOB *auth_msg, + uint8_t session_key[16]) { NTSTATUS status; NTLMSSP_STATE *ntlmssp_state = NULL; @@ -84,6 +85,8 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, goto done; } + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + /* We need to get our protocol handler into the right state. So first we ask it to generate the initial message. Actually the client has already sent its own initial message, so we're going to drop this one on the floor. @@ -115,7 +118,16 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username, data_blob_free(&reply); goto done; } + + if (ntlmssp_state->session_key.length != 16) { + DEBUG(1, ("invalid session key length %d\n", + (int)ntlmssp_state->session_key.length)); + data_blob_free(&reply); + goto done; + } + *auth_msg = data_blob(reply.data, reply.length); + memcpy(session_key, ntlmssp_state->session_key.data, 16); status = NT_STATUS_OK; done: @@ -257,9 +269,10 @@ enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *doma if (!initial.data || !challenge.data) { result = NT_STATUS_NO_MEMORY; } else { - result = do_ntlm_auth_with_hashes(name_user, name_domain, - entry->lm_hash, entry->nt_hash, - initial, challenge, &auth); + result = do_ntlm_auth_with_hashes( + name_user, name_domain, entry->lm_hash, entry->nt_hash, + initial, challenge, &auth, + state->response->data.ccache_ntlm_auth.session_key); } data_blob_free(&initial); -- 1.6.5.7 From 261060d0c7345ba5d8cadfcc47df0ea3e90425d1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 16:44:15 +0100 Subject: [PATCH 03/14] libwbclient: Actually implement wbcCredentialCache() --- nsswitch/libwbclient/wbc_pam.c | 130 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 129 insertions(+), 1 deletions(-) diff --git a/nsswitch/libwbclient/wbc_pam.c b/nsswitch/libwbclient/wbc_pam.c index 27d5be6..4b18727 100644 --- a/nsswitch/libwbclient/wbc_pam.c +++ b/nsswitch/libwbclient/wbc_pam.c @@ -1118,7 +1118,135 @@ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error) { - return WBC_ERR_NOT_IMPLEMENTED; + wbcErr status = WBC_ERR_UNKNOWN_FAILURE; + struct wbcCredentialCacheInfo *result = NULL; + struct winbindd_request request; + struct winbindd_response response; + struct wbcNamedBlob *initial_blob = NULL; + struct wbcNamedBlob *challenge_blob = NULL; + int i; + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + if (info != NULL) { + *info = NULL; + } + if (error != NULL) { + *error = NULL; + } + if ((params == NULL) + || (params->account_name == NULL) + || (params->level != WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP)) { + status = WBC_ERR_INVALID_PARAM; + goto fail; + } + + if (params->domain_name != NULL) { + status = wbcRequestResponse(WINBINDD_INFO, NULL, &response); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + snprintf(request.data.ccache_ntlm_auth.user, + sizeof(request.data.ccache_ntlm_auth.user)-1, + "%s%c%s", params->domain_name, + response.data.info.winbind_separator, + params->account_name); + } else { + strncpy(request.data.ccache_ntlm_auth.user, + params->account_name, + sizeof(request.data.ccache_ntlm_auth.user)-1); + } + request.data.ccache_ntlm_auth.uid = getuid(); + + for (i=0; inum_blobs; i++) { + if (strcasecmp(params->blobs[i].name, "initial_blob") == 0) { + initial_blob = ¶ms->blobs[i]; + break; + } + if (strcasecmp(params->blobs[i].name, "challenge_blob") == 0) { + challenge_blob = ¶ms->blobs[i]; + break; + } + } + + request.data.ccache_ntlm_auth.initial_blob_len = 0; + request.data.ccache_ntlm_auth.challenge_blob_len = 0; + request.extra_len = 0; + + if (initial_blob != NULL) { + request.data.ccache_ntlm_auth.initial_blob_len = + initial_blob->blob.length; + request.extra_len += initial_blob->blob.length; + } + if (challenge_blob != NULL) { + request.data.ccache_ntlm_auth.challenge_blob_len = + challenge_blob->blob.length; + request.extra_len += challenge_blob->blob.length; + } + + if (request.extra_len != 0) { + request.extra_data.data = talloc_array( + NULL, char, request.extra_len); + if (request.extra_data.data == NULL) { + status = WBC_ERR_NO_MEMORY; + goto fail; + } + } + if (initial_blob != NULL) { + memcpy(request.extra_data.data, + initial_blob->blob.data, initial_blob->blob.length); + } + if (challenge_blob != NULL) { + memcpy(request.extra_data.data + + request.data.ccache_ntlm_auth.initial_blob_len, + challenge_blob->blob.data, + challenge_blob->blob.length); + } + + status = wbcRequestResponse(WINBINDD_CCACHE_NTLMAUTH, &request, + &response); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + + result = talloc(NULL, struct wbcCredentialCacheInfo); + if (result == NULL) { + status = WBC_ERR_NO_MEMORY; + goto fail; + } + result->num_blobs = 0; + result->blobs = talloc(result, struct wbcNamedBlob); + if (result->blobs == NULL) { + status = WBC_ERR_NO_MEMORY; + goto fail; + } + status = wbcAddNamedBlob(&result->num_blobs, &result->blobs, + "auth_blob", 0, + (uint8_t *)response.extra_data.data, + response.data.ccache_ntlm_auth.auth_blob_len); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + status = wbcAddNamedBlob( + &result->num_blobs, &result->blobs, "session_key", 0, + response.data.ccache_ntlm_auth.session_key, + sizeof(response.data.ccache_ntlm_auth.session_key)); + if (!WBC_ERROR_IS_OK(status)) { + goto fail; + } + + if (response.extra_data.data) + free(response.extra_data.data); + *info = result; + return WBC_ERR_SUCCESS; + +fail: + TALLOC_FREE(request.extra_data.data); + if (response.extra_data.data) + free(response.extra_data.data); + talloc_free(result); + return status; } /* Authenticate a user with cached credentials */ -- 1.6.5.7 From 63ebba760570c52ac55f8c2f7eae628e83513941 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 16:47:24 +0100 Subject: [PATCH 04/14] s3: Add NTLMSSP_FEATURE_CCACHE Uses the winbind ccache to do authentication if asked to do so --- source3/Makefile.in | 52 ++++++++++++++++++++++++++------------ source3/include/ntlmssp.h | 2 + source3/libsmb/ntlmssp.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 17 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index cdf2d38..37c39ca 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1547,9 +1547,10 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) $(LIBTALLOC) $(LIBTDB) $(LIBWBCL $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) -bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/nmbd@EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(POPT_LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(ZLIB_LIBS) @@ -1581,14 +1582,16 @@ bin/net@EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(LIBWBCLIENT_LIBS) $(LIBNETAPI_LIBS) \ $(ZLIB_LIBS) -bin/profiles@EXEEXT@: $(BINARY_PREREQS) $(PROFILES_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/profiles@EXEEXT@: $(BINARY_PREREQS) $(PROFILES_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(PROFILES_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @@ -1606,21 +1609,24 @@ bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBWBCLIENT_LIBS) \ $(LIBTDB_LIBS) $(NSCD_LIBS) $(ZLIB_LIBS) -bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/smbstatus@EXEEXT@: $(BINARY_PREREQS) $(STATUS_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/smbstatus@EXEEXT@: $(BINARY_PREREQS) $(STATUS_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/smbcontrol@EXEEXT@: $(BINARY_PREREQS) $(SMBCONTROL_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/smbcontrol@EXEEXT@: $(BINARY_PREREQS) $(SMBCONTROL_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -DUSING_SMBCONTROL -o $@ \ $(SMBCONTROL_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(LDAP_LIBS) @LIBUNWIND_PTRACE@ $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/smbtree@EXEEXT@: $(BINARY_PREREQS) $(SMBTREE_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @@ -1647,9 +1653,10 @@ bin/smbget@EXEEXT@: $(BINARY_PREREQS) $(SMBGET_OBJ) @BUILD_POPT@ $(LIBTALLOC) $( $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) -bin/nmblookup@EXEEXT@: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/nmblookup@EXEEXT@: $(BINARY_PREREQS) $(NMBLOOKUP_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(POPT_LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/smbtorture@EXEEXT@: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @@ -1658,10 +1665,11 @@ bin/smbtorture@EXEEXT@: $(BINARY_PREREQS) $(SMBTORTURE_OBJ) @BUILD_POPT@ $(LIBTA $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) \ $(LIBTDB_LIBS) $(ZLIB_LIBS) $(LIBWBCLIENT_LIBS) -bin/talloctort@EXEEXT@: $(BINARY_PREREQS) $(TALLOCTORT_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/talloctort@EXEEXT@: $(BINARY_PREREQS) $(TALLOCTORT_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(TALLOCTORT_OBJ) $(LDFLAGS) \ $(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/replacetort@EXEEXT@: $(REPLACETORT_OBJ) @BUILD_POPT@ $(LIBTALLOC) @@ -1675,16 +1683,18 @@ bin/smbconftort@EXEEXT@: $(SMBCONFTORT_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/masktest@EXEEXT@: $(BINARY_PREREQS) $(MASKTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/masktest@EXEEXT@: $(BINARY_PREREQS) $(MASKTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) -bin/msgtest@EXEEXT@: $(BINARY_PREREQS) $(MSGTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/msgtest@EXEEXT@: $(BINARY_PREREQS) $(MSGTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) bin/smbcacls@EXEEXT@: $(BINARY_PREREQS) $(SMBCACLS_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @@ -1699,20 +1709,23 @@ bin/smbcquotas@EXEEXT@: $(BINARY_PREREQS) $(SMBCQUOTAS_OBJ) @BUILD_POPT@ $(LIBTA $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) -bin/eventlogadm@EXEEXT@: $(BINARY_PREREQS) $(EVTLOGADM_OBJ) $(LIBTALLOC) $(LIBTDB) +bin/eventlogadm@EXEEXT@: $(BINARY_PREREQS) $(EVTLOGADM_OBJ) $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(EVTLOGADM_OBJ) $(DYNEXP) $(LDFLAGS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBS) $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/sharesec@EXEEXT@: $(BINARY_PREREQS) $(SHARESEC_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/sharesec@EXEEXT@: $(BINARY_PREREQS) $(SHARESEC_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(SHARESEC_OBJ) $(DYNEXP) $(LDFLAGS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/locktest@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/locktest@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(LOCKTEST_OBJ) $(LDFLAGS) $(DYNEXP) \ $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) bin/nsstest@EXEEXT@: $(BINARY_PREREQS) $(NSSTEST_OBJ) @@ -1733,10 +1746,11 @@ bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ $(LIBTALLOC) @SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ $(LIBWBCLIENT_LIBS) $(ZLIB_LIBS) -bin/smbiconv@EXEEXT@: $(BINARY_PREREQS) $(SMBICONV_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/smbiconv@EXEEXT@: $(BINARY_PREREQS) $(SMBICONV_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(SMBICONV_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ $(TERMLIBS) $(DYNEXP) $(LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/log2pcap@EXEEXT@: $(BINARY_PREREQS) $(LOG2PCAP_OBJ) @BUILD_POPT@ $(LIBTALLOC) @@ -1744,9 +1758,10 @@ bin/log2pcap@EXEEXT@: $(BINARY_PREREQS) $(LOG2PCAP_OBJ) @BUILD_POPT@ $(LIBTALLOC @$(CC) -o $@ $(LOG2PCAP_OBJ) $(LDFLAGS) $(DYNEXP) \ $(POPT_LIBS) $(LIBS) $(LIBTALLOC_LIBS) -bin/locktest2@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST2_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) +bin/locktest2@EXEEXT@: $(BINARY_PREREQS) $(LOCKTEST2_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo Linking $@ @$(CC) -o $@ $(LOCKTEST2_OBJ) $(LDFLAGS) $(DYNEXP) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBS) $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) @@ -1759,6 +1774,7 @@ bin/smbfilter@EXEEXT@: $(BINARY_PREREQS) $(SMBFILTER_OBJ) @BUILD_POPT@ $(LIBTALL @echo Linking $@ @$(CC) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @@ -2513,10 +2529,11 @@ bin/vlp@EXEEXT@: $(BINARY_PREREQS) $(VLP_OBJ) $(LIBTDB) $(LIBREPLACE_LIBS) $(WINBIND_NSS_PTHREAD) \ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@ -@WINBIND_WINS_NSS@: $(BINARY_PREREQS) $(WINBIND_WINS_NSS_OBJ) $(LIBTALLOC) $(LIBTDB) +@WINBIND_WINS_NSS@: $(BINARY_PREREQS) $(WINBIND_WINS_NSS_OBJ) $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo "Linking $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(WINBIND_WINS_NSS_OBJ) \ $(LDAP_LIBS) $(KRB5LIBS) $(LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ @SONAMEFLAG@`basename $@`@NSSSONAMEVERSIONSUFFIX@ bin/winbind_krb5_locator.@SHLIBEXT@: $(BINARY_PREREQS) $(WINBIND_KRB5_LOCATOR_OBJ) $(LIBWBCLIENT) @@ -2903,11 +2920,12 @@ bin/test_lp_load@EXEEXT@: $(BINARY_PREREQS) $(TEST_LP_LOAD_OBJ) @BUILD_POPT@ $(L $(LDAP_LIBS) \ $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) -bin/dbwrap_tool@EXEEXT@: $(DBWRAP_TOOL_OBJ) $(LIBTALLOC) $(LIBTDB) +bin/dbwrap_tool@EXEEXT@: $(DBWRAP_TOOL_OBJ) $(LIBTALLOC) $(LIBTDB) $(LIBWBCLIENT) @echo "Linking $@" @$(CC) -o $@ $(DBWRAP_TOOL_OBJ)\ $(LDFLAGS) $(DYNEEXP) $(LIBS) \ $(LDAP_LIBS) \ + @LIBWBCLIENT_STATIC@ $(LIBWBCLIENT_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) install-dbwrap_tool:: bin/dbwrap_tool@EXEEXT@ diff --git a/source3/include/ntlmssp.h b/source3/include/ntlmssp.h index 9f47c9c..03a219b 100644 --- a/source3/include/ntlmssp.h +++ b/source3/include/ntlmssp.h @@ -40,6 +40,7 @@ enum NTLM_MESSAGE_TYPE #define NTLMSSP_FEATURE_SESSION_KEY 0x00000001 #define NTLMSSP_FEATURE_SIGN 0x00000002 #define NTLMSSP_FEATURE_SEAL 0x00000004 +#define NTLMSSP_FEATURE_CCACHE 0x00000008 typedef struct ntlmssp_state { @@ -50,6 +51,7 @@ typedef struct ntlmssp_state bool unicode; bool use_ntlmv2; + bool use_ccache; char *user; char *domain; char *workstation; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 60c1d49..e4ded1a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -257,6 +257,9 @@ void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list) if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + if (in_list("NTLMSSP_FEATURE_CCACHE", feature_list, true)) { + ntlmssp_state->use_ccache = true; + } } /** @@ -277,6 +280,9 @@ void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature) if (feature & NTLMSSP_FEATURE_SEAL) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; } + if (feature & NTLMSSP_FEATURE_CCACHE) { + ntlmssp_state->use_ccache = true; + } } /** @@ -1017,6 +1023,58 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, struct CHALLENGE_MESSAGE challenge; struct AUTHENTICATE_MESSAGE authenticate; + if (ntlmssp_state->use_ccache) { + struct wbcCredentialCacheParams params; + struct wbcCredentialCacheInfo *info = NULL; + struct wbcAuthErrorInfo *error = NULL; + struct wbcNamedBlob auth_blob; + struct wbcBlob *wbc_next = NULL; + struct wbcBlob *wbc_session_key = NULL; + wbcErr wbc_status; + int i; + + params.account_name = ntlmssp_state->user; + params.domain_name = ntlmssp_state->domain; + params.level = WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP; + + auth_blob.name = "challenge_blob"; + auth_blob.flags = 0; + auth_blob.blob.data = reply.data; + auth_blob.blob.length = reply.length; + params.num_blobs = 1; + params.blobs = &auth_blob; + + wbc_status = wbcCredentialCache(¶ms, &info, &error); + if (error != NULL) { + wbcFreeMemory(error); + } + if (!WBC_ERROR_IS_OK(wbc_status)) { + goto noccache; + } + + for (i=0; inum_blobs; i++) { + if (strequal(info->blobs[i].name, "auth_blob")) { + wbc_next = &info->blobs[i].blob; + } + if (strequal(info->blobs[i].name, "session_key")) { + wbc_session_key = &info->blobs[i].blob; + } + } + if ((wbc_next == NULL) || (wbc_session_key == NULL)) { + wbcFreeMemory(info); + goto noccache; + } + + *next_request = data_blob(wbc_next->data, wbc_next->length); + ntlmssp_state->session_key = data_blob( + wbc_session_key->data, wbc_session_key->length); + + wbcFreeMemory(info); + goto done; + } + +noccache: + if (!msrpc_parse(ntlmssp_state, &reply, "CdBd", "NTLMSSP", &ntlmssp_command, @@ -1230,6 +1288,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; +done: + ntlmssp_state->expected_state = NTLMSSP_DONE; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { -- 1.6.5.7 From 243791748dc2ffc03da8e7a6f3f8bbbc236c2b24 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 16:50:46 +0100 Subject: [PATCH 05/14] s3: Add ccache use to cli_session_setup_ntlmssp --- source3/include/client.h | 1 + source3/libsmb/cliconnect.c | 3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 82d94b0..aedb60a 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -266,6 +266,7 @@ struct cli_state { bool use_kerberos; bool fallback_after_kerberos; bool use_spnego; + bool use_ccache; bool got_kerberos_mechanism; /* Server supports krb5 in SPNEGO. */ bool use_oplocks; /* should we use oplocks? */ diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 715ea91..7f84fa4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -866,6 +866,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use return nt_status; } ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + if (cli->use_ccache) { + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_CCACHE); + } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; -- 1.6.5.7 From cced87bc542f88842251e39dfa3aa12417d92916 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 17:07:24 +0100 Subject: [PATCH 06/14] s3: Add -C (--use-ccache) to popt_common_credentials --- source3/include/popt_common.h | 1 + source3/include/proto.h | 3 +++ source3/lib/popt_common.c | 7 ++++++- source3/lib/util.c | 10 ++++++++++ 4 files changed, 20 insertions(+), 1 deletions(-) diff --git a/source3/include/popt_common.h b/source3/include/popt_common.h index 7237ca6..a6e43d2 100644 --- a/source3/include/popt_common.h +++ b/source3/include/popt_common.h @@ -55,6 +55,7 @@ struct user_auth_info { bool smb_encrypt; bool use_machine_account; bool fallback_after_kerberos; + bool use_ccache; }; #endif /* _POPT_COMMON_H */ diff --git a/source3/include/proto.h b/source3/include/proto.h index b3512d9..d49b07e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1107,6 +1107,9 @@ const char *get_cmdline_auth_info_password(const struct user_auth_info *auth_inf bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, const char *arg); int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info); +void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, + bool b); +bool get_cmdline_auth_info_use_ccache(const struct user_auth_info *auth_info); void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info, bool b); bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info); diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index 342309d..060382b 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -473,6 +473,7 @@ static void get_credentials_file(struct user_auth_info *auth_info, * -S,--signing * -P --machine-pass * -e --encrypt + * -C --use-ccache */ @@ -573,7 +574,9 @@ static void popt_common_credentials_callback(poptContext con, case 'e': set_cmdline_auth_info_smb_encrypt(auth_info); break; - + case 'C': + set_cmdline_auth_info_use_ccache(auth_info, true); + break; } } @@ -595,5 +598,7 @@ struct poptOption popt_common_credentials[] = { { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" }, {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" }, {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" }, + {"use-ccache", 'C', POPT_ARG_NONE, NULL, 'C', + "Use the winbind ccache for authentication" }, POPT_TABLEEND }; diff --git a/source3/lib/util.c b/source3/lib/util.c index 5fe7bce..50aa4b0 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -382,6 +382,16 @@ int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info) return auth_info->signing_state; } +void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b) +{ + auth_info->use_ccache = b; +} + +bool get_cmdline_auth_info_use_ccache(const struct user_auth_info *auth_info) +{ + return auth_info->use_ccache; +} + void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info, bool b) { -- 1.6.5.7 From 1ae71d97f228a592ef88ebd80c12ba82a658633a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 17:08:56 +0100 Subject: [PATCH 07/14] s3: Use -C in smbclient $ bin/wbinfo --ccache-save=w2k3ad\\vl%Password saving creds succeeded $ bin/smbclient //192.168.42.160/tmp -Uvl -N -C -W w2k3ad OS=[Windows Server 2003 R2 3790 Service Pack 2] Server=[Windows Server 2003 R2 5.2] smb: \> $ bin/wbinfo --ccache-save=w2k3ad\\vl%WrongPassword saving creds succeeded $ bin/smbclient //192.168.42.160/tmp -Uvl -N -C -W w2k3ad Anonymous login successful Domain=[W2K3AD] OS=[Windows Server 2003 R2 3790 Service Pack 2] Server=[Windows Server 2003 R2 5.2] tree connect failed: NT_STATUS_ACCESS_DENIED $ --- source3/libsmb/clidfs.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 0afb759..c588c16 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -154,6 +154,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, c->use_kerberos = get_cmdline_auth_info_use_kerberos(auth_info); c->fallback_after_kerberos = get_cmdline_auth_info_fallback_after_kerberos(auth_info); + c->use_ccache = get_cmdline_auth_info_use_ccache(auth_info); if (!cli_session_request(c, &calling, &called)) { char *p; -- 1.6.5.7 From 767a0d09a257b6ceed49754433468cd0cce51f72 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 17:34:13 +0100 Subject: [PATCH 08/14] s3: Add CLI_FULL_CONNECTION_USE_CCACHE --- source3/include/client.h | 1 + source3/libsmb/cliconnect.c | 3 +++ 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index aedb60a..cc32cd1 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -305,5 +305,6 @@ typedef struct file_info { #define CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS 0x0008 #define CLI_FULL_CONNECTION_OPLOCKS 0x0010 #define CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS 0x0020 +#define CLI_FULL_CONNECTION_USE_CCACHE 0x0040 #endif /* _CLIENT_H */ diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7f84fa4..6f4ae01 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2213,6 +2213,9 @@ again: cli->use_kerberos) { cli->fallback_after_kerberos = true; } + if (flags & CLI_FULL_CONNECTION_USE_CCACHE) { + cli->use_ccache = true; + } nt_status = cli_negprot(cli); if (!NT_STATUS_IS_OK(nt_status)) { -- 1.6.5.7 From 1e5b8d49e9f578546dd5dc99737733e29e92d74e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 17:35:04 +0100 Subject: [PATCH 09/14] s3: Enable -C in rpcclient --- source3/rpcclient/rpcclient.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index f6d56ad..e24538b 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -988,6 +988,9 @@ out_free: flags |= CLI_FULL_CONNECTION_USE_KERBEROS | CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } + if (get_cmdline_auth_info_use_ccache(rpcclient_auth_info)) { + flags |= CLI_FULL_CONNECTION_USE_CCACHE; + } user = talloc_strdup(frame, get_cmdline_auth_info_username(rpcclient_auth_info)); SMB_ASSERT(user != NULL); -- 1.6.5.7 From 43119a6c6c170088756f2554af2e143631bd0f66 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 18:51:58 +0100 Subject: [PATCH 10/14] s3: Fix a bug in net's use of popt In order to add --use-ccache to net, I added another "bool opt_ccache;" to struct net_context. popt did not like this, it took a while to figure out why. Popt has the lines /* XXX Check alignment, may fail on funky platforms. */ if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1))) return POPT_ERROR_NULLARG; The "bool opt_ccache;" was not aligned anymore... --- source3/utils/net.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/source3/utils/net.h b/source3/utils/net.h index 765b61b..3978459 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -70,7 +70,7 @@ struct net_context { const char *opt_exclude; const char *opt_destination; int opt_testmode; - bool opt_kerberos; + int opt_kerberos; int opt_force_full_repl; int opt_single_obj_repl; int opt_clean_old_entries; -- 1.6.5.7 From 0dfab6709ec05dc53a1a65fb93b814b9f7af4413 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 18:50:31 +0100 Subject: [PATCH 11/14] s3: add libnetapi_set_use_ccache() --- source3/lib/netapi/cm.c | 4 ++++ source3/lib/netapi/netapi.c | 6 ++++++ source3/lib/netapi/netapi.h | 6 ++++++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 9baba7b..3a624bf 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -55,6 +55,10 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, set_cmdline_auth_info_fallback_after_kerberos(auth_info, true); } + if (ctx->use_ccache) { + set_cmdline_auth_info_use_ccache(auth_info, true); + } + cli_ipc = cli_cm_open(ctx, NULL, server_name, "IPC$", auth_info, diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index e80879a..bde6fd8 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -250,6 +250,12 @@ NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx) return NET_API_STATUS_SUCCESS; } +NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx) +{ + ctx->use_ccache = true; + return NET_API_STATUS_SUCCESS; +} + /**************************************************************** ****************************************************************/ diff --git a/source3/lib/netapi/netapi.h b/source3/lib/netapi/netapi.h index 96cf225..8976ebd 100644 --- a/source3/lib/netapi/netapi.h +++ b/source3/lib/netapi/netapi.h @@ -1318,6 +1318,7 @@ struct libnetapi_ctx { char *password; char *krb5_cc_env; int use_kerberos; + int use_ccache; int disable_policy_handle_cache; void *private_data; @@ -1370,6 +1371,11 @@ NET_API_STATUS libnetapi_set_use_kerberos(struct libnetapi_ctx *ctx); /**************************************************************** ****************************************************************/ +NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx); + +/**************************************************************** +****************************************************************/ + const char *libnetapi_errstr(NET_API_STATUS status); /**************************************************************** -- 1.6.5.7 From 7c85016e5057a05f1582118827e4ebb9381f3c16 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 18:50:48 +0100 Subject: [PATCH 12/14] s3: Add --use-ccache to net --- source3/utils/net.c | 1 + source3/utils/net.h | 1 + source3/utils/net_rpc.c | 3 +++ source3/utils/net_util.c | 4 ++++ 4 files changed, 9 insertions(+), 0 deletions(-) diff --git a/source3/utils/net.c b/source3/utils/net.c index 7154abf..85c3c7d 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -770,6 +770,7 @@ static struct functable net_func[] = { {"machine-pass",'P', POPT_ARG_NONE, &c->opt_machine_pass}, {"kerberos", 'k', POPT_ARG_NONE, &c->opt_kerberos}, {"myworkgroup", 'W', POPT_ARG_STRING, &c->opt_workgroup}, + {"use-ccache", 0, POPT_ARG_NONE, &c->opt_ccache}, {"verbose", 'v', POPT_ARG_NONE, &c->opt_verbose}, {"test", 'T', POPT_ARG_NONE, &c->opt_testmode}, /* Options for 'net groupmap set' */ diff --git a/source3/utils/net.h b/source3/utils/net.h index 3978459..91e8c53 100644 --- a/source3/utils/net.h +++ b/source3/utils/net.h @@ -72,6 +72,7 @@ struct net_context { int opt_testmode; int opt_kerberos; int opt_force_full_repl; + int opt_ccache; int opt_single_obj_repl; int opt_clean_old_entries; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 05b2a7c..120f634 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -7357,6 +7357,9 @@ int net_rpc(struct net_context *c, int argc, const char **argv) if (c->opt_kerberos) { libnetapi_set_use_kerberos(c->netapi_ctx); } + if (c->opt_ccache) { + libnetapi_set_use_ccache(c->netapi_ctx); + } return net_run_function(c, argc, argv, "net rpc", func); } diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 5f66cfa..bfa56a7 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -109,6 +109,10 @@ NTSTATUS connect_to_service(struct net_context *c, flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS; } + if (c->opt_ccache) { + flags |= CLI_FULL_CONNECTION_USE_CCACHE; + } + nt_status = cli_full_connection(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, -- 1.6.5.7 From bfd296f2518afbbd1fcfc68e49bc9cc3b67a4bc1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Jan 2010 19:24:10 +0100 Subject: [PATCH 13/14] s3-libsmbclient: Add smbc_setOptionUseCCache() Can we enable this by default? This would be a change in behaviour, but this feature is just too cool for everyone to catch up in the apps. The patch would be --- source3/include/libsmbclient.h | 11 +++++++++++ source3/libsmb/libsmb_context.c | 14 ++++++++++++++ source3/libsmb/libsmb_server.c | 7 +++++++ source3/libsmb/libsmb_setget.c | 18 ++++++++++++++++++ 4 files changed, 50 insertions(+), 0 deletions(-) diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index 7de5000..dd6f93e 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -263,10 +263,13 @@ typedef struct _SMBCCTX SMBCCTX; * smbc_getOptionFallbackAFterKerberos() * smbc_setOptionNoAutoAnonymousLogin() * smbc_getOptionNoAutoAnonymousLogin() + * smbc_setOptionUseCCache() + * smbc_getOptionUseCCache() */ # define SMB_CTX_FLAG_USE_KERBEROS (1 << 0) # define SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS (1 << 1) # define SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON (1 << 2) +# define SMB_CTX_FLAG_USE_CCACHE (1 << 3) @@ -732,6 +735,14 @@ smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c); void smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b); +/** Get whether to enable use of the winbind ccache */ +smbc_bool +smbc_getOptionUseCCache(SMBCCTX *c); + +/** Set whether to enable use of the winbind ccache */ +void +smbc_setOptionUseCCache(SMBCCTX *c, smbc_bool b); + /************************************* diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index a22895f..d7f13ff 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -168,6 +168,7 @@ smbc_new_context(void) smbc_setOptionFullTimeNames(context, False); smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); + smbc_setOptionUseCCache(context, True); smbc_setOptionCaseSensitive(context, False); smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ smbc_setOptionUrlEncodeReaddirEntries(context, False); @@ -399,6 +400,10 @@ smbc_option_set(SMBCCTX *context, option_value.b = (bool) va_arg(ap, int); smbc_setOptionFallbackAfterKerberos(context, option_value.b); + } else if (strcmp(option_name, "use_ccache") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionUseCCache(context, option_value.b); + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { option_value.b = (bool) va_arg(ap, int); smbc_setOptionNoAutoAnonymousLogin(context, option_value.b); @@ -505,6 +510,13 @@ smbc_option_get(SMBCCTX *context, return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context); #endif + } else if (strcmp(option_name, "use_ccache") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionUseCCache(context); +#else + return (void *) (bool) smbc_getOptionUseCCache(context); +#endif + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) return (void *) (intptr_t) smbc_getOptionNoAutoAnonymousLogin(context); @@ -748,6 +760,8 @@ void smbc_set_credentials_with_fallback(SMBCCTX *context, set_cmdline_auth_info_signing_state(auth_info, signing_state); set_cmdline_auth_info_fallback_after_kerberos(auth_info, smbc_getOptionFallbackAfterKerberos(context)); + set_cmdline_auth_info_use_ccache( + auth_info, smbc_getOptionUseCCache(context)); set_global_myworkgroup(workgroup); TALLOC_FREE(context->internal->auth_info); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index a572acd..6ad3bf9 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -413,6 +413,10 @@ again: c->fallback_after_kerberos = True; } + if (smbc_getOptionUseCCache(context)) { + c->use_ccache = True; + } + c->timeout = smbc_getTimeout(context); /* @@ -759,6 +763,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } + if (smbc_getOptionUseCCache(context)) { + flags |= CLI_FULL_CONNECTION_USE_CCACHE; + } zero_sockaddr(&ss); nt_status = cli_full_connection(&ipc_cli, diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c index 7113c62..885f5f7 100644 --- a/source3/libsmb/libsmb_setget.c +++ b/source3/libsmb/libsmb_setget.c @@ -420,6 +420,24 @@ smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b) } } +/** Get whether to enable use of kerberos */ +smbc_bool +smbc_getOptionUseCCache(SMBCCTX *c) +{ + return c->flags & SMB_CTX_FLAG_USE_CCACHE ? True : False; +} + +/** Set whether to enable use of kerberos */ +void +smbc_setOptionUseCCache(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMB_CTX_FLAG_USE_CCACHE; + } else { + c->flags &= ~SMB_CTX_FLAG_USE_CCACHE; + } +} + /** Get the function for obtaining authentication data */ smbc_get_auth_data_fn smbc_getFunctionAuthData(SMBCCTX *c) -- 1.6.5.7 From c9b7ac8d1d7f77bd035f9fced7659bcc2b2c8a12 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 26 Jan 2010 10:51:32 +0100 Subject: [PATCH 14/14] s3: Enable use of ccache by default for libsmbclient Disable this by setting the environment variable LIBSMBCLIENT_NO_CCACHE, which has the advantage over an smb.conf option to be easily settable per application. --- source3/libsmb/libsmb_context.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index d7f13ff..c72db43 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -173,6 +173,9 @@ smbc_new_context(void) smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ smbc_setOptionUrlEncodeReaddirEntries(context, False); smbc_setOptionOneSharePerServer(context, False); + if (getenv("LIBSMBCLIENT_NO_CCACHE") == NULL) { + smbc_setOptionUseCCache(context, true); + } smbc_setFunctionAuthData(context, SMBC_get_auth_data); smbc_setFunctionCheckServer(context, SMBC_check_server); -- 1.6.5.7