Changeset 740 for vendor/current/source4/auth
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source4/auth
- Files:
-
- 13 added
- 18 deleted
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/auth/auth.h
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Standardised Authentication types 4 4 Copyright (C) Andrew Bartlett 2001 5 5 Copyright (C) Stefan Metzmacher 2005 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 23 23 24 24 #include "librpc/gen_ndr/ndr_krb5pac.h" 25 #include "librpc/gen_ndr/auth.h" 26 #include "../auth/common_auth.h" 25 27 26 28 extern const char *krbtgt_attrs[]; … … 44 46 #define AUTH_INTERFACE_VERSION 0 45 47 46 #define USER_INFO_CASE_INSENSITIVE_USERNAME 0x01 /* username may be in any case */ 47 #define USER_INFO_CASE_INSENSITIVE_PASSWORD 0x02 /* password may be in any case */ 48 #define USER_INFO_DONT_CHECK_UNIX_ACCOUNT 0x04 /* dont check unix account status */ 49 #define USER_INFO_INTERACTIVE_LOGON 0x08 /* dont check unix account status */ 50 51 enum auth_password_state { 52 AUTH_PASSWORD_RESPONSE, 53 AUTH_PASSWORD_HASH, 54 AUTH_PASSWORD_PLAIN 55 }; 56 57 struct auth_usersupplied_info 58 { 59 const char *workstation_name; 60 struct socket_address *remote_host; 61 62 uint32_t logon_parameters; 63 64 bool mapped_state; 65 /* the values the client gives us */ 66 struct { 67 const char *account_name; 68 const char *domain_name; 69 } client, mapped; 70 71 enum auth_password_state password_state; 72 73 union { 74 struct { 75 DATA_BLOB lanman; 76 DATA_BLOB nt; 77 } response; 78 struct { 79 struct samr_Password *lanman; 80 struct samr_Password *nt; 81 } hash; 82 83 char *plaintext; 84 } password; 85 uint32_t flags; 86 }; 87 88 struct auth_serversupplied_info 89 { 90 struct dom_sid *account_sid; 91 struct dom_sid *primary_group_sid; 92 93 size_t n_domain_groups; 94 struct dom_sid **domain_groups; 95 96 DATA_BLOB user_session_key; 97 DATA_BLOB lm_session_key; 98 99 const char *account_name; 100 const char *domain_name; 101 102 const char *full_name; 103 const char *logon_script; 104 const char *profile_path; 105 const char *home_directory; 106 const char *home_drive; 107 const char *logon_server; 108 109 NTTIME last_logon; 110 NTTIME last_logoff; 111 NTTIME acct_expiry; 112 NTTIME last_password_change; 113 NTTIME allow_password_change; 114 NTTIME force_password_change; 115 116 uint16_t logon_count; 117 uint16_t bad_password_count; 118 119 uint32_t acct_flags; 120 121 bool authenticated; 122 123 struct PAC_SIGNATURE_DATA pac_srv_sig, pac_kdc_sig; 124 }; 48 #define AUTH_SESSION_INFO_DEFAULT_GROUPS 0x01 /* Add the user to the default world and network groups */ 49 #define AUTH_SESSION_INFO_AUTHENTICATED 0x02 /* Add the user to the 'authenticated users' group */ 50 #define AUTH_SESSION_INFO_SIMPLE_PRIVILEGES 0x04 /* Use a trivial map between users and privilages, rather than a DB */ 125 51 126 52 struct auth_method_context; 127 53 struct auth_check_password_request; 128 54 struct auth_context; 55 struct auth_session_info; 56 struct ldb_dn; 129 57 130 58 struct auth_operations { … … 136 64 * that. It is not compatible with being a PDC. */ 137 65 138 NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge);66 NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]); 139 67 140 68 /* Given the user supplied info, check if this backend want to handle the password checking */ … … 147 75 NTSTATUS (*check_password)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, 148 76 const struct auth_usersupplied_info *user_info, 149 struct auth_serversupplied_info **server_info); 150 151 /* Lookup a 'server info' return based only on the principal */ 152 NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, 153 struct auth_context *auth_context, 154 const char *principal, 155 struct auth_serversupplied_info **server_info); 77 struct auth_user_info_dc **interim_info); 78 79 /* Lookup a 'session info interim' return based only on the principal or DN */ 80 NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, 81 struct auth_context *auth_context, 82 const char *principal, 83 struct ldb_dn *user_dn, 84 struct auth_user_info_dc **interim_info); 156 85 }; 157 86 … … 166 95 struct auth_context { 167 96 struct { 168 /* Who set this up in the first place? */ 97 /* Who set this up in the first place? */ 169 98 const char *set_by; 170 99 171 100 bool may_be_modified; 172 101 173 DATA_BLOB data; 102 DATA_BLOB data; 174 103 } challenge; 175 104 … … 186 115 struct loadparm_context *lp_ctx; 187 116 117 /* SAM database for this local machine - to fill in local groups, or to authenticate local NTLM users */ 118 struct ldb_context *sam_ctx; 119 188 120 NTSTATUS (*check_password)(struct auth_context *auth_ctx, 189 121 TALLOC_CTX *mem_ctx, 190 const struct auth_usersupplied_info *user_info, 191 struct auth_ serversupplied_info **server_info);192 193 NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, const uint8_t **_chal);122 const struct auth_usersupplied_info *user_info, 123 struct auth_user_info_dc **user_info_dc); 124 125 NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]); 194 126 195 127 bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); 196 128 197 129 NTSTATUS (*set_challenge)(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); 198 199 NTSTATUS (*get_server_info_principal)(TALLOC_CTX *mem_ctx, 200 struct auth_context *auth_context, 201 const char *principal, 202 struct auth_serversupplied_info **server_info); 203 130 131 NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, 132 struct auth_context *auth_ctx, 133 const char *principal, 134 struct ldb_dn *user_dn, 135 struct auth_user_info_dc **user_info_dc); 136 137 NTSTATUS (*generate_session_info)(TALLOC_CTX *mem_ctx, 138 struct auth_context *auth_context, 139 struct auth_user_info_dc *user_info_dc, 140 uint32_t session_info_flags, 141 struct auth_session_info **session_info); 204 142 }; 205 143 … … 211 149 int sizeof_auth_context; 212 150 int sizeof_auth_usersupplied_info; 213 int sizeof_auth_ serversupplied_info;214 }; 215 216 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, 151 int sizeof_auth_user_info_dc; 152 }; 153 154 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, 217 155 enum auth_password_state to_state, 218 156 const struct auth_usersupplied_info *user_info_in, … … 221 159 #include "auth/session.h" 222 160 #include "auth/system_session_proto.h" 161 #include "libcli/security/security.h" 223 162 224 163 struct ldb_message; 225 164 struct ldb_context; 226 struct ldb_dn;227 165 struct gensec_security; 228 229 NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal); 166 struct cli_credentials; 167 168 NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]); 230 169 NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, 231 170 struct ldb_context *sam_ctx, … … 237 176 bool allow_domain_trust, 238 177 bool password_change); 239 struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); 240 NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 178 NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, 179 struct ldb_val *dn_val, const bool only_childs, const char *filter, 180 TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, 181 unsigned int *num_res_sids); 182 struct auth_session_info *system_session(struct loadparm_context *lp_ctx); 183 NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, 241 184 const char *netbios_name, 242 185 const char *domain_name, 243 struct ldb_dn *domain_dn, 186 struct ldb_dn *domain_dn, 244 187 struct ldb_message *msg, 245 188 DATA_BLOB user_sess_key, DATA_BLOB lm_sess_key, 246 struct auth_ serversupplied_info **_server_info);247 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 189 struct auth_user_info_dc **_user_info_dc); 190 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 248 191 struct loadparm_context *lp_ctx, 249 192 struct auth_session_info **_session_info) ; 250 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status); 251 252 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, 193 194 NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, 253 195 struct tevent_context *ev, 254 196 struct messaging_context *msg, 255 197 struct loadparm_context *lp_ctx, 198 struct ldb_context *sam_ctx, 256 199 struct auth_context **auth_ctx); 257 258 NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 200 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); 201 202 NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 259 203 struct tevent_context *ev, 260 204 struct messaging_context *msg, 261 205 struct loadparm_context *lp_ctx, 262 206 struct auth_context **auth_ctx); 207 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx); 263 208 264 209 NTSTATUS auth_check_password(struct auth_context *auth_ctx, 265 210 TALLOC_CTX *mem_ctx, 266 const struct auth_usersupplied_info *user_info, 267 struct auth_ serversupplied_info **server_info);268 NTSTATUS auth _init(void);211 const struct auth_usersupplied_info *user_info, 212 struct auth_user_info_dc **user_info_dc); 213 NTSTATUS auth4_init(void); 269 214 NTSTATUS auth_register(const struct auth_operations *ops); 215 NTSTATUS server_service_auth_init(void); 270 216 NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, 271 struct tevent_context *ev, 272 struct messaging_context *msg, 273 struct loadparm_context *lp_ctx, 274 const char *nt4_domain, 275 const char *nt4_username, 276 const char *password, 277 struct auth_session_info **session_info); 278 NTSTATUS auth_check_password_recv(struct auth_check_password_request *req, 217 struct tevent_context *ev, 218 struct messaging_context *msg, 219 struct loadparm_context *lp_ctx, 220 const char *nt4_domain, 221 const char *nt4_username, 222 const char *password, 223 const uint32_t logon_parameters, 224 struct auth_session_info **session_info); 225 226 struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, 227 struct tevent_context *ev, 228 struct auth_context *auth_ctx, 229 const struct auth_usersupplied_info *user_info); 230 NTSTATUS auth_check_password_recv(struct tevent_req *req, 279 231 TALLOC_CTX *mem_ctx, 280 struct auth_serversupplied_info **server_info); 281 282 void auth_check_password_send(struct auth_context *auth_ctx, 283 const struct auth_usersupplied_info *user_info, 284 void (*callback)(struct auth_check_password_request *req, void *private_data), 285 void *private_data); 232 struct auth_user_info_dc **user_info_dc); 233 234 bool auth_challenge_may_be_modified(struct auth_context *auth_ctx); 286 235 NTSTATUS auth_context_set_challenge(struct auth_context *auth_ctx, const uint8_t chal[8], const char *set_by); 236 237 NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 238 struct auth_context *auth_ctx, 239 const char *principal, 240 struct ldb_dn *user_dn, 241 struct auth_user_info_dc **user_info_dc); 287 242 288 243 NTSTATUS samba_server_gensec_start(TALLOC_CTX *mem_ctx, -
vendor/current/source4/auth/credentials/credentials.c
r414 r740 25 25 #include "librpc/gen_ndr/samr.h" /* for struct samrPassword */ 26 26 #include "auth/credentials/credentials.h" 27 #include "auth/credentials/credentials_krb5.h"28 #include "auth/credentials/credentials_proto.h"29 27 #include "libcli/auth/libcli_auth.h" 30 28 #include "lib/events/events.h" 31 29 #include "param/param.h" 30 #include "system/filesys.h" 32 31 33 32 /** … … 38 37 { 39 38 struct cli_credentials *cred = talloc(mem_ctx, struct cli_credentials); 40 if ( !cred) {39 if (cred == NULL) { 41 40 return cred; 42 41 } 43 42 44 cred->netlogon_creds = NULL;45 cred->machine_account_pending = false;46 43 cred->workstation_obtained = CRED_UNINITIALISED; 47 44 cred->username_obtained = CRED_UNINITIALISED; … … 51 48 cred->ccache_obtained = CRED_UNINITIALISED; 52 49 cred->client_gss_creds_obtained = CRED_UNINITIALISED; 50 cred->principal_obtained = CRED_UNINITIALISED; 51 cred->keytab_obtained = CRED_UNINITIALISED; 53 52 cred->server_gss_creds_obtained = CRED_UNINITIALISED; 54 cred->keytab_obtained = CRED_UNINITIALISED;55 cred->principal_obtained = CRED_UNINITIALISED;56 53 57 54 cred->ccache_threshold = CRED_UNINITIALISED; 58 55 cred->client_gss_creds_threshold = CRED_UNINITIALISED; 59 56 57 cred->workstation = NULL; 58 cred->username = NULL; 59 cred->password = NULL; 60 60 cred->old_password = NULL; 61 cred->domain = NULL; 62 cred->realm = NULL; 63 cred->principal = NULL; 64 cred->salt_principal = NULL; 65 cred->impersonate_principal = NULL; 66 cred->target_service = NULL; 67 68 cred->bind_dn = NULL; 69 70 cred->nt_hash = NULL; 71 72 cred->lm_response.data = NULL; 73 cred->lm_response.length = 0; 74 cred->nt_response.data = NULL; 75 cred->nt_response.length = 0; 76 77 cred->ccache = NULL; 78 cred->client_gss_creds = NULL; 79 cred->keytab = NULL; 80 cred->server_gss_creds = NULL; 81 82 cred->workstation_cb = NULL; 83 cred->password_cb = NULL; 84 cred->username_cb = NULL; 85 cred->domain_cb = NULL; 86 cred->realm_cb = NULL; 87 cred->principal_cb = NULL; 88 89 cred->priv_data = NULL; 90 91 cred->netlogon_creds = NULL; 92 cred->secure_channel_type = SEC_CHAN_NULL; 93 94 cred->kvno = 0; 95 96 cred->password_last_changed_time = 0; 97 61 98 cred->smb_krb5_context = NULL; 62 cred->salt_principal = NULL; 99 100 cred->machine_account_pending = false; 101 cred->machine_account_pending_lp_ctx = NULL; 102 63 103 cred->machine_account = false; 64 104 65 cred->bind_dn = NULL;66 67 105 cred->tries = 3; 106 68 107 cred->callback_running = false; 69 108 70 109 cli_credentials_set_kerberos_state(cred, CRED_AUTO_USE_KERBEROS); 71 110 cli_credentials_set_gensec_features(cred, 0); 111 cli_credentials_set_krb_forwardable(cred, CRED_AUTO_KRB_FORWARDABLE); 72 112 73 113 return cred; … … 94 134 } 95 135 136 _PUBLIC_ void cli_credentials_set_krb_forwardable(struct cli_credentials *creds, 137 enum credentials_krb_forwardable krb_forwardable) 138 { 139 creds->krb_forwardable = krb_forwardable; 140 } 141 96 142 _PUBLIC_ enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds) 97 143 { 98 144 return creds->use_kerberos; 145 } 146 147 _PUBLIC_ enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds) 148 { 149 return creds->krb_forwardable; 99 150 } 100 151 … … 185 236 * @note Return value will never be NULL except by programmer error. 186 237 */ 187 _PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)238 const char *cli_credentials_get_principal_and_obtained(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, enum credentials_obtained *obtained) 188 239 { 189 240 if (cred->machine_account_pending) { … … 201 252 } 202 253 203 if (cred->principal_obtained < cred->username_obtained) { 254 if (cred->principal_obtained < cred->username_obtained 255 || cred->principal_obtained < MAX(cred->domain_obtained, cred->realm_obtained)) { 204 256 if (cred->domain_obtained > cred->realm_obtained) { 257 *obtained = MIN(cred->domain_obtained, cred->username_obtained); 205 258 return talloc_asprintf(mem_ctx, "%s@%s", 206 259 cli_credentials_get_username(cred), 207 260 cli_credentials_get_domain(cred)); 208 261 } else { 262 *obtained = MIN(cred->domain_obtained, cred->username_obtained); 209 263 return talloc_asprintf(mem_ctx, "%s@%s", 210 264 cli_credentials_get_username(cred), … … 212 266 } 213 267 } 268 *obtained = cred->principal_obtained; 214 269 return talloc_reference(mem_ctx, cred->principal); 270 } 271 272 /** 273 * Obtain the client principal for this credentials context. 274 * @param cred credentials context 275 * @retval The username set on this context. 276 * @note Return value will never be NULL except by programmer error. 277 */ 278 _PUBLIC_ const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx) 279 { 280 enum credentials_obtained obtained; 281 return cli_credentials_get_principal_and_obtained(cred, mem_ctx, &obtained); 215 282 } 216 283 … … 614 681 { 615 682 cli_credentials_set_username(cred, "", CRED_UNINITIALISED); 616 cli_credentials_set_domain(cred, lp _workgroup(lp_ctx), CRED_UNINITIALISED);617 cli_credentials_set_workstation(cred, lp _netbios_name(lp_ctx), CRED_UNINITIALISED);618 cli_credentials_set_realm(cred, lp _realm(lp_ctx), CRED_UNINITIALISED);683 cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_UNINITIALISED); 684 cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_UNINITIALISED); 685 cli_credentials_set_realm(cred, lpcfg_realm(lp_ctx), CRED_UNINITIALISED); 619 686 } 620 687 … … 629 696 { 630 697 char *p; 698 const char *error_string; 631 699 632 700 if (lp_ctx != NULL) { … … 660 728 661 729 if (cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) { 662 cli_credentials_set_ccache(cred, event_context_find(cred), lp_ctx, NULL, CRED_GUESS_FILE); 730 cli_credentials_set_ccache(cred, lp_ctx, NULL, CRED_GUESS_FILE, 731 &error_string); 663 732 } 664 733 } … … 691 760 { 692 761 cred->secure_channel_type = secure_channel_type; 762 } 763 764 /** 765 * Return NETLOGON secure chanel type 766 */ 767 768 _PUBLIC_ time_t cli_credentials_get_password_last_changed_time(struct cli_credentials *cred) 769 { 770 return cred->password_last_changed_time; 771 } 772 773 /** 774 * Set NETLOGON secure channel type 775 */ 776 777 _PUBLIC_ void cli_credentials_set_password_last_changed_time(struct cli_credentials *cred, 778 time_t last_changed_time) 779 { 780 cred->password_last_changed_time = last_changed_time; 693 781 } 694 782 … … 723 811 const char *username; 724 812 813 /* if bind dn is set it's not anonymous */ 814 if (cred->bind_dn) { 815 return false; 816 } 817 725 818 if (cred->machine_account_pending) { 726 819 cli_credentials_set_machine_account(cred, … … 760 853 return (cred->tries > 0); 761 854 } 855 856 _PUBLIC_ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, 857 const char **username, 858 const char **domain) 859 { 860 if (cred->principal_obtained > cred->username_obtained) { 861 *domain = talloc_strdup(mem_ctx, ""); 862 *username = cli_credentials_get_principal(cred, mem_ctx); 863 } else { 864 *domain = cli_credentials_get_domain(cred); 865 *username = cli_credentials_get_username(cred); 866 } 867 } 868 869 /** 870 * Read a named file, and parse it for username, domain, realm and password 871 * 872 * @param credentials Credentials structure on which to set the password 873 * @param file a named file to read the details from 874 * @param obtained This enum describes how 'specified' this password is 875 */ 876 877 _PUBLIC_ bool cli_credentials_parse_file(struct cli_credentials *cred, const char *file, enum credentials_obtained obtained) 878 { 879 uint16_t len = 0; 880 char *ptr, *val, *param; 881 char **lines; 882 int i, numlines; 883 884 lines = file_lines_load(file, &numlines, 0, NULL); 885 886 if (lines == NULL) 887 { 888 /* fail if we can't open the credentials file */ 889 d_printf("ERROR: Unable to open credentials file!\n"); 890 return false; 891 } 892 893 for (i = 0; i < numlines; i++) { 894 len = strlen(lines[i]); 895 896 if (len == 0) 897 continue; 898 899 /* break up the line into parameter & value. 900 * will need to eat a little whitespace possibly */ 901 param = lines[i]; 902 if (!(ptr = strchr_m (lines[i], '='))) 903 continue; 904 905 val = ptr+1; 906 *ptr = '\0'; 907 908 /* eat leading white space */ 909 while ((*val!='\0') && ((*val==' ') || (*val=='\t'))) 910 val++; 911 912 if (strwicmp("password", param) == 0) { 913 cli_credentials_set_password(cred, val, obtained); 914 } else if (strwicmp("username", param) == 0) { 915 cli_credentials_set_username(cred, val, obtained); 916 } else if (strwicmp("domain", param) == 0) { 917 cli_credentials_set_domain(cred, val, obtained); 918 } else if (strwicmp("realm", param) == 0) { 919 cli_credentials_set_realm(cred, val, obtained); 920 } 921 memset(lines[i], 0, len); 922 } 923 924 talloc_free(lines); 925 926 return true; 927 } 928 929 /** 930 * Read a named file, and parse it for a password 931 * 932 * @param credentials Credentials structure on which to set the password 933 * @param file a named file to read the password from 934 * @param obtained This enum describes how 'specified' this password is 935 */ 936 937 _PUBLIC_ bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained) 938 { 939 int fd = open(file, O_RDONLY, 0); 940 bool ret; 941 942 if (fd < 0) { 943 fprintf(stderr, "Error opening password file %s: %s\n", 944 file, strerror(errno)); 945 return false; 946 } 947 948 ret = cli_credentials_parse_password_fd(credentials, fd, obtained); 949 950 close(fd); 951 952 return ret; 953 } 954 955 956 /** 957 * Read a file descriptor, and parse it for a password (eg from a file or stdin) 958 * 959 * @param credentials Credentials structure on which to set the password 960 * @param fd open file descriptor to read the password from 961 * @param obtained This enum describes how 'specified' this password is 962 */ 963 964 _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, 965 int fd, enum credentials_obtained obtained) 966 { 967 char *p; 968 char pass[128]; 969 970 for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */ 971 p && p - pass < sizeof(pass);) { 972 switch (read(fd, p, 1)) { 973 case 1: 974 if (*p != '\n' && *p != '\0') { 975 *++p = '\0'; /* advance p, and null-terminate pass */ 976 break; 977 } 978 /* fall through */ 979 case 0: 980 if (p - pass) { 981 *p = '\0'; /* null-terminate it, just in case... */ 982 p = NULL; /* then force the loop condition to become false */ 983 break; 984 } else { 985 fprintf(stderr, "Error reading password from file descriptor %d: %s\n", fd, "empty password\n"); 986 return false; 987 } 988 989 default: 990 fprintf(stderr, "Error reading password from file descriptor %d: %s\n", 991 fd, strerror(errno)); 992 return false; 993 } 994 } 995 996 cli_credentials_set_password(credentials, pass, obtained); 997 return true; 998 } 999 1000 -
vendor/current/source4/auth/credentials/credentials.h
r414 r740 45 45 }; 46 46 47 enum credentials_krb_forwardable { 48 CRED_AUTO_KRB_FORWARDABLE = 0, /* Default, follow library defaults */ 49 CRED_NO_KRB_FORWARDABLE, /* not forwardable */ 50 CRED_FORCE_KRB_FORWARDABLE /* forwardable */ 51 }; 52 47 53 #define CLI_CRED_NTLM2 0x01 48 54 #define CLI_CRED_NTLMv2_AUTH 0x02 … … 77 83 const char *realm; 78 84 const char *principal; 79 const char *salt_principal; 85 char *salt_principal; 86 char *impersonate_principal; 87 char *target_service; 80 88 81 89 const char *bind_dn; … … 106 114 enum netr_SchannelType secure_channel_type; 107 115 int kvno; 116 time_t password_last_changed_time; 108 117 109 118 struct smb_krb5_context *smb_krb5_context; … … 120 129 enum credentials_use_kerberos use_kerberos; 121 130 131 /* Should we get a forwardable ticket? */ 132 enum credentials_krb_forwardable krb_forwardable; 133 122 134 /* gensec features which should be used for connections */ 123 135 uint32_t gensec_features; … … 131 143 132 144 struct ldb_context; 145 struct ldb_message; 133 146 struct loadparm_context; 134 147 struct ccache_container; … … 156 169 const char *cli_credentials_get_username(struct cli_credentials *cred); 157 170 int cli_credentials_get_krb5_context(struct cli_credentials *cred, 158 struct tevent_context *event_ctx,159 171 struct loadparm_context *lp_ctx, 160 172 struct smb_krb5_context **smb_krb5_context); … … 162 174 struct tevent_context *event_ctx, 163 175 struct loadparm_context *lp_ctx, 164 struct ccache_container **ccc); 176 struct ccache_container **ccc, 177 const char **error_string); 178 int cli_credentials_get_named_ccache(struct cli_credentials *cred, 179 struct tevent_context *event_ctx, 180 struct loadparm_context *lp_ctx, 181 char *ccache_name, 182 struct ccache_container **ccc, const char **error_string); 165 183 int cli_credentials_get_keytab(struct cli_credentials *cred, 166 struct tevent_context *event_ctx,167 184 struct loadparm_context *lp_ctx, 168 185 struct keytab_container **_ktc); … … 175 192 const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx); 176 193 int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, 177 struct tevent_context *event_ctx,178 194 struct loadparm_context *lp_ctx, 179 195 struct gssapi_creds_container **_gcc); … … 181 197 struct tevent_context *event_ctx, 182 198 struct loadparm_context *lp_ctx, 183 struct gssapi_creds_container **_gcc); 199 struct gssapi_creds_container **_gcc, 200 const char **error_string); 184 201 void cli_credentials_set_kerberos_state(struct cli_credentials *creds, 185 202 enum credentials_use_kerberos use_kerberos); 203 void cli_credentials_set_krb_forwardable(struct cli_credentials *creds, 204 enum credentials_krb_forwardable krb_forwardable); 186 205 bool cli_credentials_set_domain(struct cli_credentials *cred, 187 206 const char *val, … … 210 229 void cli_credentials_set_secure_channel_type(struct cli_credentials *cred, 211 230 enum netr_SchannelType secure_channel_type); 231 void cli_credentials_set_password_last_changed_time(struct cli_credentials *cred, 232 time_t last_change_time); 212 233 void cli_credentials_set_netlogon_creds(struct cli_credentials *cred, 213 234 struct netlogon_creds_CredentialState *netlogon_creds); … … 215 236 struct smb_krb5_context *smb_krb5_context); 216 237 NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred, 217 struct tevent_context *event_ctx,218 238 struct loadparm_context *lp_ctx, 219 239 const char *serviceprincipal); … … 231 251 const char *(*password_cb) (struct cli_credentials *)); 232 252 enum netr_SchannelType cli_credentials_get_secure_channel_type(struct cli_credentials *cred); 253 time_t cli_credentials_get_password_last_changed_time(struct cli_credentials *cred); 233 254 void cli_credentials_set_kvno(struct cli_credentials *cred, 234 255 int kvno); … … 241 262 enum credentials_obtained obtained); 242 263 int cli_credentials_set_keytab_name(struct cli_credentials *cred, 243 struct tevent_context *event_ctx,244 264 struct loadparm_context *lp_ctx, 245 265 const char *keytab_name, 246 266 enum credentials_obtained obtained); 247 int cli_credentials_update_keytab(struct cli_credentials *cred,248 struct tevent_context *event_ctx,249 struct loadparm_context *lp_ctx);250 267 void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features); 251 268 uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds); 252 269 int cli_credentials_set_ccache(struct cli_credentials *cred, 253 struct tevent_context *event_ctx,254 270 struct loadparm_context *lp_ctx, 255 271 const char *name, 256 enum credentials_obtained obtained); 272 enum credentials_obtained obtained, 273 const char **error_string); 257 274 bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained); 258 275 bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, … … 261 278 enum credentials_obtained obtained); 262 279 void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal); 280 void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal); 281 void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); 282 const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); 283 const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); 284 const char *cli_credentials_get_target_service(struct cli_credentials *cred); 263 285 enum credentials_use_kerberos cli_credentials_get_kerberos_state(struct cli_credentials *creds); 286 enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(struct cli_credentials *creds); 264 287 NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred, 265 struct tevent_context *event_ctx,266 288 struct loadparm_context *lp_ctx, 267 289 struct ldb_context *ldb, 268 290 const char *base, 269 const char *filter); 291 const char *filter, 292 char **error_string); 270 293 int cli_credentials_get_kvno(struct cli_credentials *cred); 271 294 295 272 296 #endif /* __CREDENTIALS_H__ */ -
vendor/current/source4/auth/credentials/credentials_krb5.c
r414 r740 28 28 #include "auth/credentials/credentials_proto.h" 29 29 #include "auth/credentials/credentials_krb5.h" 30 #include "auth/kerberos/kerberos_credentials.h" 31 #include "auth/kerberos/kerberos_util.h" 30 32 #include "param/param.h" 31 33 32 34 _PUBLIC_ int cli_credentials_get_krb5_context(struct cli_credentials *cred, 33 struct tevent_context *event_ctx,34 35 struct loadparm_context *lp_ctx, 35 36 struct smb_krb5_context **smb_krb5_context) … … 41 42 } 42 43 43 ret = smb_krb5_init_context(cred, event_ctx, lp_ctx, &cred->smb_krb5_context); 44 ret = smb_krb5_init_context(cred, NULL, lp_ctx, 45 &cred->smb_krb5_context); 44 46 if (ret) { 45 47 cred->smb_krb5_context = NULL; … … 50 52 } 51 53 52 /* This needs to be called directly after the cli_credentials_init(), 53 * otherwise we might have problems with the krb5 context already 54 * being here. 54 /* For most predictable behaviour, this needs to be called directly after the cli_credentials_init(), 55 * otherwise we may still have references to the old smb_krb5_context in a credential cache etc 55 56 */ 56 57 _PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, 57 58 struct smb_krb5_context *smb_krb5_context) 58 59 { 60 if (smb_krb5_context == NULL) { 61 talloc_unlink(cred, cred->smb_krb5_context); 62 cred->smb_krb5_context = NULL; 63 return NT_STATUS_OK; 64 } 65 59 66 if (!talloc_reference(cred, smb_krb5_context)) { 60 67 return NT_STATUS_NO_MEMORY; … … 65 72 66 73 static int cli_credentials_set_from_ccache(struct cli_credentials *cred, 67 struct ccache_container *ccache, 68 enum credentials_obtained obtained) 74 struct ccache_container *ccache, 75 enum credentials_obtained obtained, 76 const char **error_string) 69 77 { 70 78 … … 81 89 82 90 if (ret) { 83 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, 84 ret, cred); 85 DEBUG(1,("failed to get principal from ccache: %s\n", 86 err_mess)); 87 talloc_free(err_mess); 91 (*error_string) = talloc_asprintf(cred, "failed to get principal from ccache: %s\n", 92 smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, 93 ret, cred)); 88 94 return ret; 89 95 } … … 91 97 ret = krb5_unparse_name(ccache->smb_krb5_context->krb5_context, princ, &name); 92 98 if (ret) { 93 char *err_mess = smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, ret, cred); 94 DEBUG(1,("failed to unparse principal from ccache: %s\n", 95 err_mess)); 96 talloc_free(err_mess); 99 (*error_string) = talloc_asprintf(cred, "failed to unparse principal from ccache: %s\n", 100 smb_get_krb5_error_message(ccache->smb_krb5_context->krb5_context, 101 ret, cred)); 97 102 return ret; 98 103 } … … 126 131 127 132 _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, 128 struct tevent_context *event_ctx,129 struct loadparm_context *lp_ctx,130 const char *name,131 enum credentials_obtained obtained)133 struct loadparm_context *lp_ctx, 134 const char *name, 135 enum credentials_obtained obtained, 136 const char **error_string) 132 137 { 133 138 krb5_error_code ret; … … 140 145 ccc = talloc(cred, struct ccache_container); 141 146 if (!ccc) { 142 return ENOMEM; 143 } 144 145 ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, 147 (*error_string) = error_message(ENOMEM); 148 return ENOMEM; 149 } 150 151 ret = cli_credentials_get_krb5_context(cred, lp_ctx, 146 152 &ccc->smb_krb5_context); 147 153 if (ret) { 154 (*error_string) = error_message(ret); 148 155 talloc_free(ccc); 149 156 return ret; … … 151 158 if (!talloc_reference(ccc, ccc->smb_krb5_context)) { 152 159 talloc_free(ccc); 160 (*error_string) = error_message(ENOMEM); 153 161 return ENOMEM; 154 162 } … … 157 165 ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache); 158 166 if (ret) { 159 DEBUG(1,("failed to read krb5 ccache: %s: %s\n", 160 name, 161 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); 167 (*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n", 168 name, 169 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, 170 ret, ccc)); 162 171 talloc_free(ccc); 163 172 return ret; … … 166 175 ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache); 167 176 if (ret) { 168 DEBUG(3,("failed to read default krb5 ccache: %s\n", 169 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); 177 (*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n", 178 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, 179 ret, ccc)); 170 180 talloc_free(ccc); 171 181 return ret; … … 177 187 ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ); 178 188 179 if (ret) { 180 DEBUG(3,("failed to get principal from default ccache: %s\n", 181 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); 182 talloc_free(ccc); 183 return ret; 184 } 185 186 krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ); 187 188 ret = cli_credentials_set_from_ccache(cred, ccc, obtained); 189 190 if (ret) { 191 return ret; 192 } 193 194 cred->ccache = ccc; 195 cred->ccache_obtained = obtained; 196 talloc_steal(cred, ccc); 197 198 cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); 189 if (ret == 0) { 190 krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ); 191 ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); 192 193 if (ret) { 194 (*error_string) = error_message(ret); 195 return ret; 196 } 197 198 cred->ccache = ccc; 199 cred->ccache_obtained = obtained; 200 talloc_steal(cred, ccc); 201 202 cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); 203 return 0; 204 } 199 205 return 0; 200 206 } … … 202 208 203 209 static int cli_credentials_new_ccache(struct cli_credentials *cred, 204 struct tevent_context *event_ctx,205 210 struct loadparm_context *lp_ctx, 206 struct ccache_container **_ccc) 207 { 211 char *ccache_name, 212 struct ccache_container **_ccc, 213 const char **error_string) 214 { 215 bool must_free_cc_name = false; 208 216 krb5_error_code ret; 209 217 struct ccache_container *ccc = talloc(cred, struct ccache_container); 210 char *ccache_name;211 218 if (!ccc) { 212 219 return ENOMEM; 213 220 } 214 221 215 ccache_name = talloc_asprintf(ccc, "MEMORY:%p", 216 ccc); 217 218 if (!ccache_name) { 222 ret = cli_credentials_get_krb5_context(cred, lp_ctx, 223 &ccc->smb_krb5_context); 224 if (ret) { 219 225 talloc_free(ccc); 220 return ENOMEM; 221 } 222 223 ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, 224 &ccc->smb_krb5_context); 225 if (ret) { 226 talloc_free(ccc); 226 (*error_string) = talloc_asprintf(cred, "Failed to get krb5_context: %s", 227 error_message(ret)); 227 228 return ret; 228 229 } 229 230 if (!talloc_reference(ccc, ccc->smb_krb5_context)) { 230 231 talloc_free(ccc); 231 return ENOMEM; 232 (*error_string) = strerror(ENOMEM); 233 return ENOMEM; 234 } 235 236 if (!ccache_name) { 237 must_free_cc_name = true; 238 ccache_name = talloc_asprintf(ccc, "MEMORY:%p", 239 ccc); 240 241 if (!ccache_name) { 242 talloc_free(ccc); 243 (*error_string) = strerror(ENOMEM); 244 return ENOMEM; 245 } 232 246 } 233 247 … … 235 249 &ccc->ccache); 236 250 if (ret) { 237 DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n", 238 ccache_name, 239 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); 251 (*error_string) = talloc_asprintf(cred, "failed to resolve a krb5 ccache (%s): %s\n", 252 ccache_name, 253 smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, 254 ret, ccc)); 240 255 talloc_free(ccache_name); 241 256 talloc_free(ccc); … … 243 258 } 244 259 245 talloc_set_destructor(ccc, free_mccache); 246 247 talloc_free(ccache_name); 260 if (strncasecmp(ccache_name, "MEMORY:", 7) == 0) { 261 talloc_set_destructor(ccc, free_mccache); 262 } else { 263 talloc_set_destructor(ccc, free_dccache); 264 } 265 266 if (must_free_cc_name) { 267 talloc_free(ccache_name); 268 } 248 269 249 270 *_ccc = ccc; 250 271 251 return ret; 252 } 253 254 _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred, 255 struct tevent_context *event_ctx, 256 struct loadparm_context *lp_ctx, 257 struct ccache_container **ccc) 272 return 0; 273 } 274 275 _PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, 276 struct tevent_context *event_ctx, 277 struct loadparm_context *lp_ctx, 278 char *ccache_name, 279 struct ccache_container **ccc, 280 const char **error_string) 258 281 { 259 282 krb5_error_code ret; 283 enum credentials_obtained obtained; 260 284 261 285 if (cred->machine_account_pending) { … … 269 293 } 270 294 if (cli_credentials_is_anonymous(cred)) { 295 (*error_string) = "Cannot get anonymous kerberos credentials"; 271 296 return EINVAL; 272 297 } 273 298 274 ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, ccc);275 if (ret) { 276 return ret; 277 } 278 279 ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, (*ccc)->ccache);299 ret = cli_credentials_new_ccache(cred, lp_ctx, ccache_name, ccc, error_string); 300 if (ret) { 301 return ret; 302 } 303 304 ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string); 280 305 if (ret) { 281 306 return ret; … … 283 308 284 309 ret = cli_credentials_set_from_ccache(cred, *ccc, 285 (MAX(MAX(cred->principal_obtained, 286 cred->username_obtained), 287 cred->password_obtained))); 310 obtained, error_string); 288 311 289 312 cred->ccache = *ccc; … … 293 316 } 294 317 cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); 295 return ret; 318 return 0; 319 } 320 321 _PUBLIC_ int cli_credentials_get_ccache(struct cli_credentials *cred, 322 struct tevent_context *event_ctx, 323 struct loadparm_context *lp_ctx, 324 struct ccache_container **ccc, 325 const char **error_string) 326 { 327 return cli_credentials_get_named_ccache(cred, event_ctx, lp_ctx, NULL, ccc, error_string); 328 } 329 330 /* We have good reason to think the ccache in these credentials is invalid - blow it away */ 331 static void cli_credentials_unconditionally_invalidate_client_gss_creds(struct cli_credentials *cred) 332 { 333 if (cred->client_gss_creds_obtained > CRED_UNINITIALISED) { 334 talloc_unlink(cred, cred->client_gss_creds); 335 cred->client_gss_creds = NULL; 336 } 337 cred->client_gss_creds_obtained = CRED_UNINITIALISED; 296 338 } 297 339 … … 317 359 } 318 360 361 /* We have good reason to think this CCACHE is invalid. Blow it away */ 362 static void cli_credentials_unconditionally_invalidate_ccache(struct cli_credentials *cred) 363 { 364 if (cred->ccache_obtained > CRED_UNINITIALISED) { 365 talloc_unlink(cred, cred->ccache); 366 cred->ccache = NULL; 367 } 368 cred->ccache_obtained = CRED_UNINITIALISED; 369 370 cli_credentials_unconditionally_invalidate_client_gss_creds(cred); 371 } 372 319 373 _PUBLIC_ void cli_credentials_invalidate_ccache(struct cli_credentials *cred, 320 374 enum credentials_obtained obtained) … … 349 403 350 404 _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, 351 struct tevent_context *event_ctx, 352 struct loadparm_context *lp_ctx, 353 struct gssapi_creds_container **_gcc) 405 struct tevent_context *event_ctx, 406 struct loadparm_context *lp_ctx, 407 struct gssapi_creds_container **_gcc, 408 const char **error_string) 354 409 { 355 410 int ret = 0; … … 366 421 } 367 422 368 ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, 369 &ccache );423 ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, 424 &ccache, error_string); 370 425 if (ret) { 371 426 DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); … … 375 430 gcc = talloc(cred, struct gssapi_creds_container); 376 431 if (!gcc) { 432 (*error_string) = error_message(ENOMEM); 377 433 return ENOMEM; 378 434 } … … 380 436 maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, 381 437 &gcc->creds); 438 if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) { 439 /* This CCACHE is no good. Ensure we don't use it again */ 440 cli_credentials_unconditionally_invalidate_ccache(cred); 441 442 /* Now try again to get a ccache */ 443 ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, 444 &ccache, error_string); 445 if (ret) { 446 DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret))); 447 return ret; 448 } 449 450 maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, 451 &gcc->creds); 452 453 } 454 382 455 if (maj_stat) { 383 456 talloc_free(gcc); … … 387 460 ret = EINVAL; 388 461 } 462 (*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret)); 389 463 return ret; 390 464 } … … 409 483 410 484 maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds, 411 num_ktypes, etypes); 485 num_ktypes, 486 (int32_t *) etypes); 412 487 krb5_xfree (etypes); 413 488 if (maj_stat) { … … 418 493 ret = EINVAL; 419 494 } 495 (*error_string) = talloc_asprintf(cred, "gss_krb5_set_allowable_enctypes failed: %s", error_message(ret)); 420 496 return ret; 421 497 } … … 433 509 ret = EINVAL; 434 510 } 511 (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret)); 435 512 return ret; 436 513 } … … 455 532 456 533 int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, 457 struct tevent_context *event_ctx,458 534 struct loadparm_context *lp_ctx, 459 535 gss_cred_id_t gssapi_cred, 460 enum credentials_obtained obtained) 536 enum credentials_obtained obtained, 537 const char **error_string) 461 538 { 462 539 int ret; … … 470 547 gcc = talloc(cred, struct gssapi_creds_container); 471 548 if (!gcc) { 472 return ENOMEM; 473 } 474 475 ret = cli_credentials_new_ccache(cred, event_ctx, lp_ctx, &ccc); 549 (*error_string) = error_message(ENOMEM); 550 return ENOMEM; 551 } 552 553 ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string); 476 554 if (ret != 0) { 477 555 return ret; … … 486 564 ret = EINVAL; 487 565 } 566 if (ret) { 567 (*error_string) = error_message(ENOMEM); 568 } 488 569 } 489 570 490 571 if (ret == 0) { 491 ret = cli_credentials_set_from_ccache(cred, ccc, obtained );572 ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); 492 573 } 493 574 cred->ccache = ccc; … … 510 591 */ 511 592 _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, 512 struct tevent_context *event_ctx, 513 struct loadparm_context *lp_ctx, 514 struct keytab_container **_ktc) 593 struct loadparm_context *lp_ctx, 594 struct keytab_container **_ktc) 515 595 { 516 596 krb5_error_code ret; 517 597 struct keytab_container *ktc; 518 598 struct smb_krb5_context *smb_krb5_context; 519 const char **enctype_strings;520 599 TALLOC_CTX *mem_ctx; 521 600 … … 530 609 } 531 610 532 ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx,611 ret = cli_credentials_get_krb5_context(cred, lp_ctx, 533 612 &smb_krb5_context); 534 613 if (ret) { … … 541 620 } 542 621 543 enctype_strings = cli_credentials_get_enctype_strings(cred);544 545 622 ret = smb_krb5_create_memory_keytab(mem_ctx, cred, 546 smb_krb5_context, 547 enctype_strings, &ktc); 623 smb_krb5_context, &ktc); 548 624 if (ret) { 549 625 talloc_free(mem_ctx); … … 565 641 566 642 _PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred, 567 struct tevent_context *event_ctx, 568 struct loadparm_context *lp_ctx, 569 const char *keytab_name, 570 enum credentials_obtained obtained) 643 struct loadparm_context *lp_ctx, 644 const char *keytab_name, 645 enum credentials_obtained obtained) 571 646 { 572 647 krb5_error_code ret; … … 579 654 } 580 655 581 ret = cli_credentials_get_krb5_context(cred, event_ctx,lp_ctx, &smb_krb5_context);656 ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context); 582 657 if (ret) { 583 658 return ret; … … 604 679 } 605 680 606 _PUBLIC_ int cli_credentials_update_keytab(struct cli_credentials *cred,607 struct tevent_context *event_ctx,608 struct loadparm_context *lp_ctx)609 {610 krb5_error_code ret;611 struct keytab_container *ktc;612 struct smb_krb5_context *smb_krb5_context;613 const char **enctype_strings;614 TALLOC_CTX *mem_ctx;615 616 mem_ctx = talloc_new(cred);617 if (!mem_ctx) {618 return ENOMEM;619 }620 621 ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context);622 if (ret) {623 talloc_free(mem_ctx);624 return ret;625 }626 627 enctype_strings = cli_credentials_get_enctype_strings(cred);628 629 ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc);630 if (ret != 0) {631 talloc_free(mem_ctx);632 return ret;633 }634 635 ret = smb_krb5_update_keytab(mem_ctx, cred, smb_krb5_context, enctype_strings, ktc);636 637 talloc_free(mem_ctx);638 return ret;639 }640 641 681 /* Get server gss credentials (in gsskrb5, this means the keytab) */ 642 682 643 683 _PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, 644 struct tevent_context *event_ctx, 645 struct loadparm_context *lp_ctx, 646 struct gssapi_creds_container **_gcc) 684 struct loadparm_context *lp_ctx, 685 struct gssapi_creds_container **_gcc) 647 686 { 648 687 int ret = 0; … … 653 692 TALLOC_CTX *mem_ctx; 654 693 krb5_principal princ; 655 656 if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, 657 MAX(cred->principal_obtained, 658 cred->username_obtained)))) { 659 *_gcc = cred->server_gss_creds; 660 return 0; 661 } 662 663 ret = cli_credentials_get_krb5_context(cred, event_ctx, lp_ctx, &smb_krb5_context); 664 if (ret) { 665 return ret; 666 } 667 668 ret = cli_credentials_get_keytab(cred, event_ctx, lp_ctx, &ktc); 669 if (ret) { 670 DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); 671 return ret; 672 } 694 const char *error_string; 695 enum credentials_obtained obtained; 673 696 674 697 mem_ctx = talloc_new(cred); … … 677 700 } 678 701 679 ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ); 680 if (ret) { 681 DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", 682 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 683 ret, mem_ctx))); 702 ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context); 703 if (ret) { 704 return ret; 705 } 706 707 ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string); 708 if (ret) { 709 DEBUG(1,("cli_credentials_get_server_gss_creds: making krb5 principal failed (%s)\n", 710 error_string)); 684 711 talloc_free(mem_ctx); 712 return ret; 713 } 714 715 if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) { 716 talloc_free(mem_ctx); 717 *_gcc = cred->server_gss_creds; 718 return 0; 719 } 720 721 ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc); 722 if (ret) { 723 DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); 685 724 return ret; 686 725 } … … 732 771 733 772 734 const char **cli_credentials_get_enctype_strings(struct cli_credentials *cred)735 {736 /* If this is ever made user-configurable, we need to add code737 * to remove/hide the other entries from the generated738 * keytab */739 static const char *default_enctypes[] = {740 "des-cbc-md5",741 "aes256-cts-hmac-sha1-96",742 "des3-cbc-sha1",743 "arcfour-hmac-md5",744 NULL745 };746 return default_enctypes;747 }748 749 773 const char *cli_credentials_get_salt_principal(struct cli_credentials *cred) 750 774 { … … 754 778 _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal) 755 779 { 780 talloc_free(cred->salt_principal); 756 781 cred->salt_principal = talloc_strdup(cred, principal); 757 782 } 758 783 759 784 /* The 'impersonate_principal' is used to allow on Kerberos principal 785 * (and it's associated keytab etc) to impersonate another. The 786 * ability to do this is controlled by the KDC, but it is generally 787 * permitted to impersonate anyone to yourself. This allows any 788 * member of the domain to get the groups of a user. This is also 789 * known as S4U2Self */ 790 791 const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred) 792 { 793 return cred->impersonate_principal; 794 } 795 796 _PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal) 797 { 798 talloc_free(cred->impersonate_principal); 799 cred->impersonate_principal = talloc_strdup(cred, principal); 800 } 801 802 /* when impersonating for S4U2Self we need to set the target principal 803 * to ourself, as otherwise we would need additional rights. 804 * Similarly, we may only be authorized to do general impersonation to 805 * some particular services. 806 * 807 * Likewise, password changes typically require a ticket to kpasswd/realm directly, not via a TGT 808 * 809 * NULL means that tickets will be obtained for the krbtgt service. 810 */ 811 812 const char *cli_credentials_get_target_service(struct cli_credentials *cred) 813 { 814 return cred->target_service; 815 } 816 817 _PUBLIC_ void cli_credentials_set_target_service(struct cli_credentials *cred, const char *target_service) 818 { 819 talloc_free(cred->target_service); 820 cred->target_service = talloc_strdup(cred, target_service); 821 } 822 -
vendor/current/source4/auth/credentials/credentials_krb5.h
r414 r740 34 34 /* Manually prototyped here to avoid needing gss headers in most callers */ 35 35 int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, 36 struct tevent_context *event_ctx,37 36 struct loadparm_context *lp_ctx, 38 37 gss_cred_id_t gssapi_cred, 39 enum credentials_obtained obtained); 38 enum credentials_obtained obtained, 39 const char **error_string); 40 40 41 41 /* Manually prototyped here to avoid needing krb5 headers in most callers */ … … 43 43 struct cli_credentials *credentials, 44 44 struct smb_krb5_context *smb_krb5_context, 45 krb5_principal *princ); 45 krb5_principal *princ, 46 enum credentials_obtained *obtained, 47 const char **error_string); 48 krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx, 49 struct cli_credentials *credentials, 50 struct smb_krb5_context *smb_krb5_context, 51 krb5_principal *princ, 52 const char **error_string); 46 53 54 void cli_credentials_invalidate_client_gss_creds(struct cli_credentials *cred, 55 enum credentials_obtained obtained); 56 47 57 #endif /* __CREDENTIALS_KRB5_H__ */ -
vendor/current/source4/auth/credentials/credentials_ntlm.c
r414 r740 27 27 #include "libcli/auth/libcli_auth.h" 28 28 #include "auth/credentials/credentials.h" 29 30 _PUBLIC_ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *cred, TALLOC_CTX *mem_ctx,31 const char **username,32 const char **domain)33 {34 if (cred->principal_obtained > cred->username_obtained) {35 *domain = talloc_strdup(mem_ctx, "");36 *username = cli_credentials_get_principal(cred, mem_ctx);37 } else {38 *domain = cli_credentials_get_domain(cred);39 *username = cli_credentials_get_username(cred);40 }41 }42 29 43 30 _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred, TALLOC_CTX *mem_ctx, -
vendor/current/source4/auth/credentials/pycredentials.c
r414 r740 17 17 */ 18 18 19 #include <Python.h> 19 20 #include "includes.h" 20 #include <Python.h>21 21 #include "pycredentials.h" 22 22 #include "param/param.h" … … 25 25 #include "libcli/util/pyerrors.h" 26 26 #include "param/pyparam.h" 27 28 #ifndef Py_RETURN_NONE 29 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 30 #endif 27 #include <tevent.h> 31 28 32 29 static PyObject *PyString_FromStringOrNULL(const char *str) … … 197 194 } 198 195 196 static PyObject *py_creds_set_krb_forwardable(py_talloc_Object *self, PyObject *args) 197 { 198 int state; 199 if (!PyArg_ParseTuple(args, "i", &state)) 200 return NULL; 201 202 cli_credentials_set_krb_forwardable(PyCredentials_AsCliCredentials(self), state); 203 Py_RETURN_NONE; 204 } 205 199 206 static PyObject *py_creds_guess(py_talloc_Object *self, PyObject *args) 200 207 { 201 208 PyObject *py_lp_ctx = Py_None; 202 209 struct loadparm_context *lp_ctx; 210 TALLOC_CTX *mem_ctx; 211 struct cli_credentials *creds; 212 213 creds = PyCredentials_AsCliCredentials(self); 214 203 215 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) 204 216 return NULL; 205 217 206 lp_ctx = lp_from_py_object(py_lp_ctx); 207 if (lp_ctx == NULL) 208 return NULL; 209 210 cli_credentials_guess(PyCredentials_AsCliCredentials(self), lp_ctx); 218 mem_ctx = talloc_new(NULL); 219 if (mem_ctx == NULL) { 220 PyErr_NoMemory(); 221 return NULL; 222 } 223 224 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 225 if (lp_ctx == NULL) { 226 talloc_free(mem_ctx); 227 return NULL; 228 } 229 230 cli_credentials_guess(creds, lp_ctx); 231 232 talloc_free(mem_ctx); 211 233 212 234 Py_RETURN_NONE; … … 218 240 struct loadparm_context *lp_ctx; 219 241 NTSTATUS status; 242 struct cli_credentials *creds; 243 TALLOC_CTX *mem_ctx; 244 245 creds = PyCredentials_AsCliCredentials(self); 246 220 247 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) 221 248 return NULL; 222 249 223 lp_ctx = lp_from_py_object(py_lp_ctx); 224 if (lp_ctx == NULL) 225 return NULL; 226 227 status = cli_credentials_set_machine_account(PyCredentials_AsCliCredentials(self), lp_ctx); 250 mem_ctx = talloc_new(NULL); 251 if (mem_ctx == NULL) { 252 PyErr_NoMemory(); 253 return NULL; 254 } 255 256 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 257 if (lp_ctx == NULL) { 258 talloc_free(mem_ctx); 259 return NULL; 260 } 261 262 status = cli_credentials_set_machine_account(creds, lp_ctx); 263 talloc_free(mem_ctx); 264 228 265 PyErr_NTSTATUS_IS_ERR_RAISE(status); 229 266 230 267 Py_RETURN_NONE; 231 268 } 269 270 PyObject *PyCredentialCacheContainer_from_ccache_container(struct ccache_container *ccc) 271 { 272 PyCredentialCacheContainerObject *py_ret; 273 274 if (ccc == NULL) { 275 Py_RETURN_NONE; 276 } 277 278 py_ret = (PyCredentialCacheContainerObject *)PyCredentialCacheContainer.tp_alloc(&PyCredentialCacheContainer, 0); 279 if (py_ret == NULL) { 280 PyErr_NoMemory(); 281 return NULL; 282 } 283 py_ret->mem_ctx = talloc_new(NULL); 284 py_ret->ccc = talloc_reference(py_ret->mem_ctx, ccc); 285 return (PyObject *)py_ret; 286 } 287 288 289 static PyObject *py_creds_get_named_ccache(py_talloc_Object *self, PyObject *args) 290 { 291 PyObject *py_lp_ctx = Py_None; 292 char *ccache_name; 293 struct loadparm_context *lp_ctx; 294 struct ccache_container *ccc; 295 struct tevent_context *event_ctx; 296 int ret; 297 const char *error_string; 298 struct cli_credentials *creds; 299 TALLOC_CTX *mem_ctx; 300 301 creds = PyCredentials_AsCliCredentials(self); 302 303 if (!PyArg_ParseTuple(args, "|Os", &py_lp_ctx, &ccache_name)) 304 return NULL; 305 306 mem_ctx = talloc_new(NULL); 307 if (mem_ctx == NULL) { 308 PyErr_NoMemory(); 309 return NULL; 310 } 311 312 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 313 if (lp_ctx == NULL) { 314 talloc_free(mem_ctx); 315 return NULL; 316 } 317 318 event_ctx = tevent_context_init(mem_ctx); 319 320 ret = cli_credentials_get_named_ccache(creds, event_ctx, lp_ctx, 321 ccache_name, &ccc, &error_string); 322 talloc_unlink(mem_ctx, lp_ctx); 323 if (ret == 0) { 324 talloc_steal(ccc, event_ctx); 325 talloc_free(mem_ctx); 326 return PyCredentialCacheContainer_from_ccache_container(ccc); 327 } 328 329 PyErr_SetString(PyExc_RuntimeError, error_string?error_string:"NULL"); 330 331 talloc_free(mem_ctx); 332 return NULL; 333 } 334 335 static PyObject *py_creds_set_gensec_features(py_talloc_Object *self, PyObject *args) 336 { 337 unsigned int gensec_features; 338 339 if (!PyArg_ParseTuple(args, "I", &gensec_features)) 340 return NULL; 341 342 cli_credentials_set_gensec_features(PyCredentials_AsCliCredentials(self), gensec_features); 343 344 Py_RETURN_NONE; 345 } 346 347 static PyObject *py_creds_get_gensec_features(py_talloc_Object *self, PyObject *args) 348 { 349 unsigned int gensec_features; 350 351 gensec_features = cli_credentials_get_gensec_features(PyCredentials_AsCliCredentials(self)); 352 return PyInt_FromLong(gensec_features); 353 } 354 232 355 233 356 static PyMethodDef py_creds_methods[] = { … … 285 408 { "set_kerberos_state", (PyCFunction)py_creds_set_kerberos_state, METH_VARARGS, 286 409 NULL }, 410 { "set_krb_forwardable", (PyCFunction)py_creds_set_krb_forwardable, METH_VARARGS, 411 NULL }, 287 412 { "guess", (PyCFunction)py_creds_guess, METH_VARARGS, NULL }, 288 413 { "set_machine_account", (PyCFunction)py_creds_set_machine_account, METH_VARARGS, NULL }, 414 { "get_named_ccache", (PyCFunction)py_creds_get_named_ccache, METH_VARARGS, NULL }, 415 { "set_gensec_features", (PyCFunction)py_creds_set_gensec_features, METH_VARARGS, NULL }, 416 { "get_gensec_features", (PyCFunction)py_creds_get_gensec_features, METH_NOARGS, NULL }, 289 417 { NULL } 290 418 }; … … 293 421 .tp_name = "Credentials", 294 422 .tp_basicsize = sizeof(py_talloc_Object), 295 .tp_dealloc = py_talloc_dealloc,296 423 .tp_new = py_creds_new, 297 424 .tp_flags = Py_TPFLAGS_DEFAULT, … … 299 426 }; 300 427 428 429 PyTypeObject PyCredentialCacheContainer = { 430 .tp_name = "CredentialCacheContainer", 431 .tp_basicsize = sizeof(py_talloc_Object), 432 .tp_flags = Py_TPFLAGS_DEFAULT, 433 }; 434 301 435 void initcredentials(void) 302 436 { 303 437 PyObject *m; 438 PyTypeObject *talloc_type = PyTalloc_GetObjectType(); 439 if (talloc_type == NULL) 440 return; 441 442 PyCredentials.tp_base = PyCredentialCacheContainer.tp_base = talloc_type; 304 443 305 444 if (PyType_Ready(&PyCredentials) < 0) 445 return; 446 447 if (PyType_Ready(&PyCredentialCacheContainer) < 0) 306 448 return; 307 449 … … 314 456 PyModule_AddObject(m, "MUST_USE_KERBEROS", PyInt_FromLong(CRED_MUST_USE_KERBEROS)); 315 457 458 PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE", PyInt_FromLong(CRED_AUTO_KRB_FORWARDABLE)); 459 PyModule_AddObject(m, "NO_KRB_FORWARDABLE", PyInt_FromLong(CRED_NO_KRB_FORWARDABLE)); 460 PyModule_AddObject(m, "FORCE_KRB_FORWARDABLE", PyInt_FromLong(CRED_FORCE_KRB_FORWARDABLE)); 461 316 462 Py_INCREF(&PyCredentials); 317 463 PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials); 318 } 464 Py_INCREF(&PyCredentialCacheContainer); 465 PyModule_AddObject(m, "CredentialCacheContainer", (PyObject *)&PyCredentialCacheContainer); 466 } -
vendor/current/source4/auth/credentials/pycredentials.h
r414 r740 21 21 22 22 #include "auth/credentials/credentials.h" 23 #include "pytalloc.h"23 #include <pytalloc.h> 24 24 25 PyAPI_DATA(PyTypeObject) PyCredentials; 25 extern PyTypeObject PyCredentials; 26 extern PyTypeObject PyCredentialCacheContainer; 27 typedef struct { 28 PyObject_HEAD 29 TALLOC_CTX *mem_ctx; 30 struct ccache_container *ccc; 31 } PyCredentialCacheContainerObject; 26 32 #define PyCredentials_Check(py_obj) PyObject_TypeCheck(py_obj, &PyCredentials) 27 33 #define PyCredentials_AsCliCredentials(py_obj) py_talloc_get_type(py_obj, struct cli_credentials) -
vendor/current/source4/auth/credentials/tests/simple.c
r414 r740 107 107 struct torture_suite *torture_local_credentials(TALLOC_CTX *mem_ctx) 108 108 { 109 struct torture_suite *suite = torture_suite_create(mem_ctx, 110 "CREDENTIALS"); 109 struct torture_suite *suite = torture_suite_create(mem_ctx, "credentials"); 111 110 112 111 torture_suite_add_simple_test(suite, "init", test_init); -
vendor/current/source4/auth/gensec/cyrus_sasl.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include " auth/auth.h"23 #include "lib/tsocket/tsocket.h" 24 24 #include "auth/credentials/credentials.h" 25 25 #include "auth/gensec/gensec.h" 26 26 #include "auth/gensec/gensec_proto.h" 27 #include "lib/socket/socket.h"28 27 #include <sasl/sasl.h> 29 28 … … 31 30 sasl_conn_t *conn; 32 31 int step; 32 bool wrap; 33 33 }; 34 34 … … 119 119 const char *service = gensec_get_target_service(gensec_security); 120 120 const char *target_name = gensec_get_target_hostname(gensec_security); 121 struct socket_address *local_socket_addr = gensec_get_my_addr(gensec_security);122 struct socket_address *remote_socket_addr = gensec_get_peer_addr(gensec_security);121 const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security); 122 const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security); 123 123 char *local_addr = NULL; 124 124 char *remote_addr = NULL; … … 127 127 sasl_callback_t *callbacks; 128 128 129 gensec_sasl_state = talloc (gensec_security, struct gensec_sasl_state);129 gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state); 130 130 if (!gensec_sasl_state) { 131 131 return NT_STATUS_NO_MEMORY; … … 155 155 gensec_security->private_data = gensec_sasl_state; 156 156 157 if ( local_socket_addr) {158 local_addr = talloc_asprintf(gensec_sasl_state, 159 160 local_socket_addr->addr,161 local_socket_addr->port);162 } 163 164 if ( remote_socket_addr) {165 remote_addr = talloc_asprintf(gensec_sasl_state, 166 167 remote_socket_addr->addr,168 remote_socket_addr->port);157 if (tlocal_addr) { 158 local_addr = talloc_asprintf(gensec_sasl_state, 159 "%s;%d", 160 tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state), 161 tsocket_address_inet_port(tlocal_addr)); 162 } 163 164 if (tremote_addr) { 165 remote_addr = talloc_asprintf(gensec_sasl_state, 166 "%s;%d", 167 tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state), 168 tsocket_address_inet_port(tremote_addr)); 169 169 } 170 170 gensec_sasl_state->step = 0; … … 175 175 &gensec_sasl_state->conn); 176 176 177 if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) {177 if (sasl_ret == SASL_OK) { 178 178 sasl_security_properties_t props; 179 179 talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose); 180 180 181 181 ZERO_STRUCT(props); 182 182 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 183 183 props.min_ssf = 1; 184 props.max_ssf = 1; 185 props.maxbufsize = 65536; 186 gensec_sasl_state->wrap = true; 184 187 } 185 188 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 186 189 props.min_ssf = 40; 187 } 188 189 props.max_ssf = UINT_MAX; 190 props.maxbufsize = 65536; 190 props.max_ssf = UINT_MAX; 191 props.maxbufsize = 65536; 192 gensec_sasl_state->wrap = true; 193 } 194 191 195 sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props); 192 if (sasl_ret != SASL_OK) { 193 return sasl_nt_status(sasl_ret); 194 } 195 196 } else { 196 } 197 if (sasl_ret != SASL_OK) { 197 198 DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn))); 198 199 } … … 263 264 const char *out_data; 264 265 unsigned int out_len; 265 266 int sasl_ret = sasl_encode(gensec_sasl_state->conn, 267 (char*)in->data, in->length, &out_data, 268 &out_len); 266 unsigned len_permitted; 267 int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 268 (const void**)&len_permitted); 269 if (sasl_ret != SASL_OK) { 270 return sasl_nt_status(sasl_ret); 271 } 272 len_permitted = MIN(len_permitted, in->length); 273 274 sasl_ret = sasl_encode(gensec_sasl_state->conn, 275 (char*)in->data, len_permitted, &out_data, 276 &out_len); 269 277 if (sasl_ret == SASL_OK) { 270 278 *out = data_blob_talloc(out_mem_ctx, out_data, out_len); … … 283 291 struct gensec_sasl_state); 284 292 sasl_ssf_t ssf; 285 int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 293 int sasl_ret; 294 295 /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */ 296 if (!gensec_sasl_state->wrap) { 297 return false; 298 } 299 300 sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF, 286 301 (const void**)&ssf); 287 302 if (sasl_ret != SASL_OK) { -
vendor/current/source4/auth/gensec/gensec.c
r414 r740 22 22 23 23 #include "includes.h" 24 #include " auth/auth.h"24 #include "system/network.h" 25 25 #include "lib/events/events.h" 26 #include "lib/socket/socket.h" 27 #include "lib/tsocket/tsocket.h" 28 #include "../lib/util/tevent_ntstatus.h" 26 29 #include "librpc/rpc/dcerpc.h" 27 30 #include "auth/credentials/credentials.h" 28 31 #include "auth/gensec/gensec.h" 29 #include "auth/gensec/gensec_proto.h" 32 #include "auth/auth.h" 33 #include "auth/system_session_proto.h" 30 34 #include "param/param.h" 35 #include "lib/util/tsort.h" 31 36 32 37 /* the list of currently registered GENSEC backends */ … … 43 48 bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct gensec_security *security) 44 49 { 45 return lp _parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);50 return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled); 46 51 } 47 52 … … 503 508 @param gensec_security Returned GENSEC context pointer. 504 509 @note The mem_ctx is only a parent and may be NULL. 505 @note, the auth context is moved to be a childof the510 @note, the auth context is moved to be a referenced pointer of the 506 511 @ gensec_security return 507 512 */ … … 517 522 } 518 523 519 (*gensec_security) = talloc (mem_ctx, struct gensec_security);524 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security); 520 525 NT_STATUS_HAVE_NO_MEMORY(*gensec_security); 521 522 (*gensec_security)->ops = NULL;523 (*gensec_security)->private_data = NULL;524 525 ZERO_STRUCT((*gensec_security)->target);526 ZERO_STRUCT((*gensec_security)->peer_addr);527 ZERO_STRUCT((*gensec_security)->my_addr);528 529 (*gensec_security)->subcontext = false;530 (*gensec_security)->want_features = 0;531 526 532 527 (*gensec_security)->event_ctx = ev; 533 528 SMB_ASSERT(settings->lp_ctx != NULL); 534 529 (*gensec_security)->settings = talloc_reference(*gensec_security, settings); 535 (*gensec_security)->auth_context = talloc_steal(*gensec_security, auth_context); 530 531 /* We need to reference this, not steal, as the caller may be 532 * python, which won't like it if we steal it's object away 533 * from it */ 534 (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context); 536 535 537 536 return NT_STATUS_OK; … … 550 549 struct gensec_security **gensec_security) 551 550 { 552 (*gensec_security) = talloc (mem_ctx, struct gensec_security);551 (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security); 553 552 NT_STATUS_HAVE_NO_MEMORY(*gensec_security); 554 553 … … 593 592 return status; 594 593 } 594 595 595 596 596 597 /** … … 712 713 return oid_string; 713 714 } 714 715 716 /** 717 * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO 715 716 /** 717 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO 718 718 * 719 719 */ … … 982 982 } 983 983 984 static void gensec_update_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te, 985 struct timeval t, void *ptr) 986 { 987 struct gensec_update_request *req = talloc_get_type(ptr, struct gensec_update_request); 988 req->status = req->gensec_security->ops->update(req->gensec_security, req, req->in, &req->out); 989 req->callback.fn(req, req->callback.private_data); 990 } 991 984 struct gensec_update_state { 985 struct tevent_immediate *im; 986 struct gensec_security *gensec_security; 987 DATA_BLOB in; 988 DATA_BLOB out; 989 }; 990 991 static void gensec_update_async_trigger(struct tevent_context *ctx, 992 struct tevent_immediate *im, 993 void *private_data); 992 994 /** 993 995 * Next state function for the GENSEC state machine async version 994 * 996 * 997 * @param mem_ctx The memory context for the request 998 * @param ev The event context for the request 995 999 * @param gensec_security GENSEC State 996 1000 * @param in The request, as a DATA_BLOB 997 * @param callback The function that will be called when the operation is 998 * finished, it should return gensec_update_recv() to get output 999 * @param private_data A private pointer that will be passed to the callback function 1000 */ 1001 1002 _PUBLIC_ void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in, 1003 void (*callback)(struct gensec_update_request *req, void *private_data), 1004 void *private_data) 1005 { 1006 struct gensec_update_request *req = NULL; 1007 struct tevent_timer *te = NULL; 1008 1009 req = talloc(gensec_security, struct gensec_update_request); 1010 if (!req) goto failed; 1011 req->gensec_security = gensec_security; 1012 req->in = in; 1013 req->out = data_blob(NULL, 0); 1014 req->callback.fn = callback; 1015 req->callback.private_data = private_data; 1016 1017 te = event_add_timed(gensec_security->event_ctx, req, 1018 timeval_zero(), 1019 gensec_update_async_timed_handler, req); 1020 if (!te) goto failed; 1021 1022 return; 1023 1024 failed: 1025 talloc_free(req); 1026 callback(NULL, private_data); 1001 * 1002 * @return The request handle or NULL on no memory failure 1003 */ 1004 1005 _PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx, 1006 struct tevent_context *ev, 1007 struct gensec_security *gensec_security, 1008 const DATA_BLOB in) 1009 { 1010 struct tevent_req *req; 1011 struct gensec_update_state *state = NULL; 1012 1013 req = tevent_req_create(mem_ctx, &state, 1014 struct gensec_update_state); 1015 if (req == NULL) { 1016 return NULL; 1017 } 1018 1019 state->gensec_security = gensec_security; 1020 state->in = in; 1021 state->out = data_blob(NULL, 0); 1022 state->im = tevent_create_immediate(state); 1023 if (tevent_req_nomem(state->im, req)) { 1024 return tevent_req_post(req, ev); 1025 } 1026 1027 tevent_schedule_immediate(state->im, ev, 1028 gensec_update_async_trigger, 1029 req); 1030 1031 return req; 1032 } 1033 1034 static void gensec_update_async_trigger(struct tevent_context *ctx, 1035 struct tevent_immediate *im, 1036 void *private_data) 1037 { 1038 struct tevent_req *req = 1039 talloc_get_type_abort(private_data, struct tevent_req); 1040 struct gensec_update_state *state = 1041 tevent_req_data(req, struct gensec_update_state); 1042 NTSTATUS status; 1043 1044 status = gensec_update(state->gensec_security, state, 1045 state->in, &state->out); 1046 if (tevent_req_nterror(req, status)) { 1047 return; 1048 } 1049 1050 tevent_req_done(req); 1027 1051 } 1028 1052 … … 1030 1054 * Next state function for the GENSEC state machine 1031 1055 * 1032 * @param req GENSEC updaterequest state1056 * @param req request state 1033 1057 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on 1034 1058 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx … … 1036 1060 * or NT_STATUS_OK if the user is authenticated. 1037 1061 */ 1038 _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out) 1039 { 1062 _PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req, 1063 TALLOC_CTX *out_mem_ctx, 1064 DATA_BLOB *out) 1065 { 1066 struct gensec_update_state *state = 1067 tevent_req_data(req, struct gensec_update_state); 1040 1068 NTSTATUS status; 1041 1069 1042 NT_STATUS_HAVE_NO_MEMORY(req); 1043 1044 *out = req->out; 1070 if (tevent_req_is_nterror(req, &status)) { 1071 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 1072 tevent_req_received(req); 1073 return status; 1074 } 1075 } else { 1076 status = NT_STATUS_OK; 1077 } 1078 1079 *out = state->out; 1045 1080 talloc_steal(out_mem_ctx, out->data); 1046 status = req->status; 1047 1048 talloc_free(req); 1081 1082 tevent_req_received(req); 1049 1083 return status; 1050 1084 } … … 1162 1196 } 1163 1197 1164 /** 1165 * Set (and talloc_reference) local and peer socket addresses onto a socket context on the GENSEC context 1198 /** 1199 * Set (and talloc_reference) local and peer socket addresses onto a socket 1200 * context on the GENSEC context. 1166 1201 * 1167 1202 * This is so that kerberos can include these addresses in … … 1169 1204 */ 1170 1205 1171 _PUBLIC_ NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr) 1172 { 1173 gensec_security->my_addr = my_addr; 1174 if (my_addr && !talloc_reference(gensec_security, my_addr)) { 1206 /** 1207 * @brief Set the local gensec address. 1208 * 1209 * @param gensec_security The gensec security context to use. 1210 * 1211 * @param remote The local address to set. 1212 * 1213 * @return On success NT_STATUS_OK is returned or an NT_STATUS 1214 * error. 1215 */ 1216 _PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security, 1217 const struct tsocket_address *local) 1218 { 1219 TALLOC_FREE(gensec_security->local_addr); 1220 1221 if (local == NULL) { 1222 return NT_STATUS_OK; 1223 } 1224 1225 gensec_security->local_addr = tsocket_address_copy(local, gensec_security); 1226 if (gensec_security->local_addr == NULL) { 1175 1227 return NT_STATUS_NO_MEMORY; 1176 1228 } 1229 1177 1230 return NT_STATUS_OK; 1178 1231 } 1179 1232 1180 _PUBLIC_ NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr) 1181 { 1182 gensec_security->peer_addr = peer_addr; 1183 if (peer_addr && !talloc_reference(gensec_security, peer_addr)) { 1233 /** 1234 * @brief Set the remote gensec address. 1235 * 1236 * @param gensec_security The gensec security context to use. 1237 * 1238 * @param remote The remote address to set. 1239 * 1240 * @return On success NT_STATUS_OK is returned or an NT_STATUS 1241 * error. 1242 */ 1243 _PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security, 1244 const struct tsocket_address *remote) 1245 { 1246 TALLOC_FREE(gensec_security->remote_addr); 1247 1248 if (remote == NULL) { 1249 return NT_STATUS_OK; 1250 } 1251 1252 gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security); 1253 if (gensec_security->remote_addr == NULL) { 1184 1254 return NT_STATUS_NO_MEMORY; 1185 1255 } 1256 1186 1257 return NT_STATUS_OK; 1187 1258 } 1188 1259 1189 struct socket_address *gensec_get_my_addr(struct gensec_security *gensec_security) 1190 { 1191 if (gensec_security->my_addr) { 1192 return gensec_security->my_addr; 1193 } 1194 1195 /* We could add a 'set sockaddr' call, and do a lookup. This 1196 * would avoid needing to do system calls if nothing asks. */ 1197 return NULL; 1198 } 1199 1200 _PUBLIC_ struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security) 1201 { 1202 if (gensec_security->peer_addr) { 1203 return gensec_security->peer_addr; 1204 } 1205 1206 /* We could add a 'set sockaddr' call, and do a lookup. This 1207 * would avoid needing to do system calls if nothing asks. 1208 * However, this is not appropriate for the peer addres on 1209 * datagram sockets */ 1210 return NULL; 1211 } 1212 1213 1260 /** 1261 * @brief Get the local address from a gensec security context. 1262 * 1263 * @param gensec_security The security context to get the address from. 1264 * 1265 * @return The address as tsocket_address which could be NULL if 1266 * no address is set. 1267 */ 1268 _PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security) 1269 { 1270 if (gensec_security == NULL) { 1271 return NULL; 1272 } 1273 return gensec_security->local_addr; 1274 } 1275 1276 /** 1277 * @brief Get the remote address from a gensec security context. 1278 * 1279 * @param gensec_security The security context to get the address from. 1280 * 1281 * @return The address as tsocket_address which could be NULL if 1282 * no address is set. 1283 */ 1284 _PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security) 1285 { 1286 if (gensec_security == NULL) { 1287 return NULL; 1288 } 1289 return gensec_security->remote_addr; 1290 } 1214 1291 1215 1292 /** … … 1219 1296 */ 1220 1297 1221 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 1298 _PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal) 1222 1299 { 1223 1300 gensec_security->target.principal = talloc_strdup(gensec_security, principal); … … 1235 1312 1236 1313 return NULL; 1314 } 1315 1316 NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx, 1317 struct gensec_security *gensec_security, 1318 struct auth_user_info_dc *user_info_dc, 1319 struct auth_session_info **session_info) 1320 { 1321 NTSTATUS nt_status; 1322 uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; 1323 if (user_info_dc->info->authenticated) { 1324 flags |= AUTH_SESSION_INFO_AUTHENTICATED; 1325 } 1326 if (gensec_security->auth_context) { 1327 nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context, 1328 user_info_dc, 1329 flags, 1330 session_info); 1331 } else { 1332 flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES; 1333 nt_status = auth_generate_session_info(mem_ctx, 1334 NULL, 1335 NULL, 1336 user_info_dc, flags, 1337 session_info); 1338 } 1339 return nt_status; 1237 1340 } 1238 1341 … … 1292 1395 int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value) 1293 1396 { 1294 return lp _parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);1397 return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value); 1295 1398 } 1296 1399 1297 1400 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value) 1298 1401 { 1299 return lp _parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);1402 return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value); 1300 1403 } 1301 1404 … … 1306 1409 { 1307 1410 static bool initialized = false; 1308 extern NTSTATUS gensec_sasl_init(void); 1309 extern NTSTATUS gensec_krb5_init(void); 1310 extern NTSTATUS gensec_schannel_init(void); 1311 extern NTSTATUS gensec_spnego_init(void); 1312 extern NTSTATUS gensec_gssapi_init(void); 1313 extern NTSTATUS gensec_ntlmssp_init(void); 1314 1411 #define _MODULE_PROTO(init) extern NTSTATUS init(void); 1412 STATIC_gensec_MODULES_PROTO; 1315 1413 init_module_fn static_init[] = { STATIC_gensec_MODULES }; 1316 1414 init_module_fn *shared_init; … … 1326 1424 talloc_free(shared_init); 1327 1425 1328 qsort(generic_security_ops, gensec_num_backends, sizeof(*generic_security_ops), QSORT_CASTsort_gensec);1426 TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec); 1329 1427 1330 1428 return NT_STATUS_OK; -
vendor/current/source4/auth/gensec/gensec.h
r414 r740 27 27 #include "libcli/util/ntstatus.h" 28 28 29 #define GENSEC_SASL_NAME_NTLMSSP "NTLM" 30 29 31 #define GENSEC_OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10" 30 32 #define GENSEC_OID_SPNEGO "1.3.6.1.5.5.2" … … 70 72 struct gensec_settings; 71 73 struct tevent_context; 72 73 struct gensec_update_request { 74 struct gensec_security *gensec_security; 75 void *private_data; 76 DATA_BLOB in; 77 DATA_BLOB out; 78 NTSTATUS status; 79 struct { 80 void (*fn)(struct gensec_update_request *req, void *private_data); 81 void *private_data; 82 } callback; 83 }; 74 struct tevent_req; 84 75 85 76 struct gensec_settings { 86 77 struct loadparm_context *lp_ctx; 87 struct smb_iconv_convenience *iconv_convenience;88 78 const char *target_hostname; 89 79 }; … … 170 160 uint32_t want_features; 171 161 struct tevent_context *event_ctx; 172 struct socket_address *my_addr, *peer_addr;162 struct tsocket_address *local_addr, *remote_addr; 173 163 struct gensec_settings *settings; 174 164 … … 191 181 struct socket_context; 192 182 struct auth_context; 183 struct auth_user_info_dc; 193 184 194 185 NTSTATUS gensec_socket_init(struct gensec_security *gensec_security, … … 232 223 NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 233 224 const DATA_BLOB in, DATA_BLOB *out); 234 void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in, 235 void (*callback)(struct gensec_update_request *req, void *private_data), 236 void *private_data); 237 NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); 225 struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx, 226 struct tevent_context *ev, 227 struct gensec_security *gensec_security, 228 const DATA_BLOB in); 229 NTSTATUS gensec_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out); 238 230 void gensec_want_feature(struct gensec_security *gensec_security, 239 231 uint32_t feature); … … 251 243 const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); 252 244 struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); 253 struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security);254 245 NTSTATUS gensec_init(struct loadparm_context *lp_ctx); 255 246 NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security, … … 284 275 NTSTATUS gensec_session_info(struct gensec_security *gensec_security, 285 276 struct auth_session_info **session_info); 286 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status);277 NTSTATUS nt_status_squash(NTSTATUS nt_status); 287 278 struct netlogon_creds_CredentialState; 288 279 NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, 289 280 TALLOC_CTX *mem_ctx, 290 281 struct netlogon_creds_CredentialState **creds); 291 NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr); 292 NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr); 282 283 284 NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security, 285 const struct tsocket_address *local); 286 NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security, 287 const struct tsocket_address *remote); 288 const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security); 289 const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security); 293 290 294 291 NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security, … … 316 313 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value); 317 314 315 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal); 316 318 317 #endif /* __GENSEC_H__ */ -
vendor/current/source4/auth/gensec/gensec.pc.in
r414 r740 7 7 Name: gensec 8 8 Description: Generic Security Library 9 Version: 0.0.110 Libs: -L${libdir} -lgensec9 Version: @PACKAGE_VERSION@ 10 Libs: @LIB_RPATH@ -L${libdir} -lgensec 11 11 Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1 -
vendor/current/source4/auth/gensec/gensec_gssapi.c
r414 r740 28 28 #include "librpc/gen_ndr/krb5pac.h" 29 29 #include "auth/auth.h" 30 #include "lib/ldb/include/ldb.h"30 #include <ldb.h> 31 31 #include "auth/auth_sam.h" 32 32 #include "librpc/rpc/dcerpc.h" … … 41 41 #include <gssapi/gssapi_spnego.h> 42 42 #include "auth/gensec/gensec_gssapi.h" 43 #include "lib/util/util_net.h" 43 44 44 45 static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); … … 147 148 struct gensec_gssapi_state *gensec_gssapi_state; 148 149 krb5_error_code ret; 149 struct gsskrb5_send_to_kdc send_to_kdc;150 151 gensec_gssapi_state = talloc (gensec_security, struct gensec_gssapi_state);150 const char *realm; 151 152 gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state); 152 153 if (!gensec_gssapi_state) { 153 154 return NT_STATUS_NO_MEMORY; 154 155 } 155 156 gensec_gssapi_state->gss_exchange_count = 0;157 gensec_gssapi_state->max_wrap_buf_size158 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);159 160 gensec_gssapi_state->sasl = false;161 gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;162 156 163 157 gensec_security->private_data = gensec_gssapi_state; 164 158 165 159 gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT; 160 161 /* TODO: Fill in channel bindings */ 162 gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; 163 166 164 gensec_gssapi_state->server_name = GSS_C_NO_NAME; 167 165 gensec_gssapi_state->client_name = GSS_C_NO_NAME; 168 gensec_gssapi_state->lucid = NULL;169 170 /* TODO: Fill in channel bindings */171 gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;172 166 173 167 gensec_gssapi_state->want_flags = 0; 168 174 169 if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) { 175 170 gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG; … … 188 183 } 189 184 190 gensec_gssapi_state->got_flags = 0;191 192 gensec_gssapi_state->session_key = data_blob(NULL, 0);193 gensec_gssapi_state->pac = data_blob(NULL, 0);194 195 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;196 gensec_gssapi_state->sig_size = 0;197 198 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);199 200 185 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 201 186 gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG; … … 207 192 gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE; 208 193 } 194 195 gensec_gssapi_state->got_flags = 0; 209 196 210 197 switch (gensec_security->ops->auth_type) { … … 218 205 } 219 206 220 send_to_kdc.func = smb_krb5_send_and_recv_func; 221 send_to_kdc.ptr = gensec_security->event_ctx; 222 223 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 224 if (ret) { 225 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 226 talloc_free(gensec_gssapi_state); 227 return NT_STATUS_INTERNAL_ERROR; 228 } 229 if (lp_realm(gensec_security->settings->lp_ctx) && *lp_realm(gensec_security->settings->lp_ctx)) { 230 char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->settings->lp_ctx)); 231 if (!upper_realm) { 232 DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->settings->lp_ctx))); 233 talloc_free(gensec_gssapi_state); 234 return NT_STATUS_NO_MEMORY; 235 } 236 ret = gsskrb5_set_default_realm(upper_realm); 237 talloc_free(upper_realm); 238 if (ret) { 239 DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n")); 240 talloc_free(gensec_gssapi_state); 241 return NT_STATUS_INTERNAL_ERROR; 242 } 243 } 244 245 /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ 246 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 247 if (ret) { 248 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); 249 talloc_free(gensec_gssapi_state); 250 return NT_STATUS_INTERNAL_ERROR; 251 } 252 253 ret = smb_krb5_init_context(gensec_gssapi_state, 254 gensec_security->event_ctx, 207 gensec_gssapi_state->session_key = data_blob(NULL, 0); 208 gensec_gssapi_state->pac = data_blob(NULL, 0); 209 210 ret = smb_krb5_init_context(gensec_gssapi_state, 211 NULL, 255 212 gensec_security->settings->lp_ctx, 256 213 &gensec_gssapi_state->smb_krb5_context); … … 261 218 return NT_STATUS_INTERNAL_ERROR; 262 219 } 220 221 gensec_gssapi_state->client_cred = NULL; 222 gensec_gssapi_state->server_cred = NULL; 223 224 gensec_gssapi_state->lucid = NULL; 225 226 gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; 227 228 gensec_gssapi_state->sasl = false; 229 gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; 230 gensec_gssapi_state->sasl_protection = 0; 231 232 gensec_gssapi_state->max_wrap_buf_size 233 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536); 234 gensec_gssapi_state->gss_exchange_count = 0; 235 gensec_gssapi_state->sig_size = 0; 236 237 talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor); 238 239 realm = lpcfg_realm(gensec_security->settings->lp_ctx); 240 if (realm != NULL) { 241 ret = gsskrb5_set_default_realm(realm); 242 if (ret) { 243 DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n")); 244 talloc_free(gensec_gssapi_state); 245 return NT_STATUS_INTERNAL_ERROR; 246 } 247 } 248 249 /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ 250 ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); 251 if (ret) { 252 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); 253 talloc_free(gensec_gssapi_state); 254 return NT_STATUS_INTERNAL_ERROR; 255 } 256 263 257 return NT_STATUS_OK; 264 258 } … … 286 280 } else { 287 281 ret = cli_credentials_get_server_gss_creds(machine_account, 288 gensec_security->event_ctx,289 282 gensec_security->settings->lp_ctx, &gcc); 290 283 if (ret) { … … 323 316 OM_uint32 maj_stat, min_stat; 324 317 const char *hostname = gensec_get_target_hostname(gensec_security); 325 const char *principal;326 318 struct gssapi_creds_container *gcc; 319 const char *error_string; 327 320 328 321 if (!hostname) { … … 346 339 gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 347 340 348 principal = gensec_get_target_principal(gensec_security);349 if ( principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {341 gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security); 342 if (gensec_gssapi_state->target_principal) { 350 343 name_type = GSS_C_NULL_OID; 351 344 } else { 352 principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",345 gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s", 353 346 gensec_get_target_service(gensec_security), 354 hostname );355 356 name_type = GSS_C_NT_ HOSTBASED_SERVICE;357 } 358 name_token.value = discard_const_p(uint8_t, principal);359 name_token.length = strlen( principal);347 hostname, lpcfg_realm(gensec_security->settings->lp_ctx)); 348 349 name_type = GSS_C_NT_USER_NAME; 350 } 351 name_token.value = discard_const_p(uint8_t, gensec_gssapi_state->target_principal); 352 name_token.length = strlen(gensec_gssapi_state->target_principal); 360 353 361 354 … … 373 366 ret = cli_credentials_get_client_gss_creds(creds, 374 367 gensec_security->event_ctx, 375 gensec_security->settings->lp_ctx, &gcc );368 gensec_security->settings->lp_ctx, &gcc, &error_string); 376 369 switch (ret) { 377 370 case 0: 378 371 break; 379 372 case KRB5KDC_ERR_PREAUTH_FAILED: 373 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 374 DEBUG(1, ("Wrong username or password: %s\n", error_string)); 380 375 return NT_STATUS_LOGON_FAILURE; 381 376 case KRB5_KDC_UNREACH: 382 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); 383 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 377 DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string)); 378 return NT_STATUS_NO_LOGON_SERVERS; 379 case KRB5_CC_NOTFOUND: 380 case KRB5_CC_END: 381 DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string)); 382 return NT_STATUS_TIME_DIFFERENCE_AT_DC; 384 383 default: 385 DEBUG(1, ("Aquiring initiator credentials failed \n"));384 DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string)); 386 385 return NT_STATUS_UNSUCCESSFUL; 387 386 } … … 460 459 case GENSEC_CLIENT: 461 460 { 461 struct gsskrb5_send_to_kdc send_to_kdc; 462 krb5_error_code ret; 463 send_to_kdc.func = smb_krb5_send_and_recv_func; 464 send_to_kdc.ptr = gensec_security->event_ctx; 465 466 min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc); 467 if (min_stat) { 468 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 469 return NT_STATUS_INTERNAL_ERROR; 470 } 471 462 472 maj_stat = gss_init_sec_context(&min_stat, 463 473 gensec_gssapi_state->client_cred->creds, … … 476 486 gensec_gssapi_state->gss_oid = gss_oid_p; 477 487 } 488 489 send_to_kdc.func = smb_krb5_send_and_recv_func; 490 send_to_kdc.ptr = NULL; 491 492 ret = gsskrb5_set_send_to_kdc(&send_to_kdc); 493 if (ret) { 494 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n")); 495 return NT_STATUS_INTERNAL_ERROR; 496 } 497 478 498 break; 479 499 } … … 516 536 * is more work to do */ 517 537 if (gensec_gssapi_state->sasl) { 518 /* Due to a very subtle interaction519 * with SASL and the LDAP libs, we520 * must ensure the data pointer is521 * != NULL, but the length is 0.522 *523 * This ensures we send a 'zero524 * length' (rather than NULL) response525 */526 527 if (!out->data) {528 out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");529 }530 531 538 gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG; 532 539 return NT_STATUS_MORE_PROCESSING_REQUIRED; … … 535 542 536 543 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 537 DEBUG(5, ("GSSAPI Connection will be cryptographic ly sealed\n"));544 DEBUG(5, ("GSSAPI Connection will be cryptographically sealed\n")); 538 545 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 539 DEBUG(5, ("GSSAPI Connection will be cryptographic ly signed\n"));546 DEBUG(5, ("GSSAPI Connection will be cryptographically signed\n")); 540 547 } else { 541 548 DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n")); … … 551 558 } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) { 552 559 switch (min_stat) { 560 case KRB5KRB_AP_ERR_TKT_NYV: 561 DEBUG(1, ("Error with ticket to contact %s: possible clock skew between us and the KDC or target server: %s\n", 562 gensec_gssapi_state->target_principal, 563 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 564 return NT_STATUS_TIME_DIFFERENCE_AT_DC; /* Make SPNEGO ignore us, we can't go any further here */ 565 case KRB5KRB_AP_ERR_TKT_EXPIRED: 566 DEBUG(1, ("Error with ticket to contact %s: ticket is expired, possible clock skew between us and the KDC or target server: %s\n", 567 gensec_gssapi_state->target_principal, 568 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 569 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 553 570 case KRB5_KDC_UNREACH: 554 DEBUG(3, ("Cannot reach a KDC we require: %s\n", 555 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 556 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 571 DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n", 572 gensec_gssapi_state->target_principal, 573 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 574 return NT_STATUS_NO_LOGON_SERVERS; /* Make SPNEGO ignore us, we can't go any further here */ 557 575 case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: 558 DEBUG(3, ("Server is not registered with our KDC: %s\n", 559 gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 576 DEBUG(3, ("Server %s is not registered with our KDC: %s\n", 577 gensec_gssapi_state->target_principal, 578 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 560 579 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 561 580 case KRB5KRB_AP_ERR_MSG_TYPE: … … 563 582 return NT_STATUS_INVALID_PARAMETER; 564 583 default: 565 DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n", 584 DEBUG(1, ("GSS %s Update(krb5)(%d) Update failed: %s\n", 585 gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server", 566 586 gensec_gssapi_state->gss_exchange_count, 567 587 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 569 589 } 570 590 } else { 571 DEBUG(1, ("GSS Update(%d) failed: %s\n", 591 DEBUG(1, ("GSS %s Update(%d) failed: %s\n", 592 gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server", 572 593 gensec_gssapi_state->gss_exchange_count, 573 594 gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); … … 623 644 gensec_gssapi_state->max_wrap_buf_size); 624 645 gensec_gssapi_state->sasl_protection = 0; 625 if ( gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {626 if ( security_supported & NEG_SEAL) {646 if (security_supported & NEG_SEAL) { 647 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 627 648 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 628 649 } 629 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 630 if (security_supported & NEG_SIGN) { 650 } 651 if (security_supported & NEG_SIGN) { 652 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 631 653 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 632 654 } 633 } else if (security_supported & NEG_NONE) { 655 } 656 if (security_supported & NEG_NONE) { 634 657 gensec_gssapi_state->sasl_protection |= NEG_NONE; 635 } else { 636 DEBUG(1, ("Remote server does not support unprotected connections")); 658 } 659 if (gensec_gssapi_state->sasl_protection == 0) { 660 DEBUG(1, ("Remote server does not support unprotected connections\n")); 637 661 return NT_STATUS_ACCESS_DENIED; 638 662 } … … 667 691 668 692 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 669 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographic ly sealed\n"));693 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically sealed\n")); 670 694 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 671 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographic ly signed\n"));695 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically signed\n")); 672 696 } else { 673 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographic ly protection\n"));697 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographically protection\n")); 674 698 } 675 699 … … 768 792 security_accepted = maxlength_accepted[0]; 769 793 maxlength_accepted[0] = '\0'; 770 794 771 795 /* Rest is the proposed max wrap length */ 772 796 gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0), … … 774 798 775 799 gensec_gssapi_state->sasl_protection = 0; 776 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 777 if (security_accepted & NEG_SEAL) { 778 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 779 } 780 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 781 if (security_accepted & NEG_SIGN) { 782 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 783 } 784 } else if (security_accepted & NEG_NONE) { 800 if (security_accepted & NEG_SEAL) { 801 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 802 DEBUG(1, ("Remote client wanted seal, but gensec refused\n")); 803 return NT_STATUS_ACCESS_DENIED; 804 } 805 gensec_gssapi_state->sasl_protection |= NEG_SEAL; 806 } 807 if (security_accepted & NEG_SIGN) { 808 if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 809 DEBUG(1, ("Remote client wanted sign, but gensec refused\n")); 810 return NT_STATUS_ACCESS_DENIED; 811 } 812 gensec_gssapi_state->sasl_protection |= NEG_SIGN; 813 } 814 if (security_accepted & NEG_NONE) { 785 815 gensec_gssapi_state->sasl_protection |= NEG_NONE; 786 } else {787 DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better"));788 return NT_STATUS_ACCESS_DENIED;789 816 } 790 817 … … 792 819 gensec_gssapi_state->sasl_state = STAGE_DONE; 793 820 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 794 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographic ly sealed\n"));821 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically sealed\n")); 795 822 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 796 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographic ly signed\n"));823 DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically signed\n")); 797 824 } else { 798 825 DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n")); … … 1231 1258 struct gensec_gssapi_state *gensec_gssapi_state 1232 1259 = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); 1233 struct auth_ serversupplied_info *server_info= NULL;1260 struct auth_user_info_dc *user_info_dc = NULL; 1234 1261 struct auth_session_info *session_info = NULL; 1235 1262 OM_uint32 maj_stat, min_stat; 1236 1263 gss_buffer_desc pac; 1237 1264 DATA_BLOB pac_blob; 1265 struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL; 1266 struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL; 1238 1267 1239 1268 if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length) … … 1266 1295 */ 1267 1296 if (pac_blob.length) { 1268 nt_status = kerberos_pac_blob_to_server_info(mem_ctx, 1269 gensec_security->settings->iconv_convenience, 1270 pac_blob, 1271 gensec_gssapi_state->smb_krb5_context->krb5_context, 1272 &server_info); 1297 pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 1298 if (!pac_srv_sig) { 1299 talloc_free(mem_ctx); 1300 return NT_STATUS_NO_MEMORY; 1301 } 1302 pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA); 1303 if (!pac_kdc_sig) { 1304 talloc_free(mem_ctx); 1305 return NT_STATUS_NO_MEMORY; 1306 } 1307 1308 nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx, 1309 pac_blob, 1310 gensec_gssapi_state->smb_krb5_context->krb5_context, 1311 &user_info_dc, 1312 pac_srv_sig, 1313 pac_kdc_sig); 1273 1314 if (!NT_STATUS_IS_OK(nt_status)) { 1274 1315 talloc_free(mem_ctx); … … 1305 1346 DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", 1306 1347 gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); 1307 nt_status = gensec_security->auth_context->get_ server_info_principal(mem_ctx,1348 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 1308 1349 gensec_security->auth_context, 1309 1350 principal_string, 1310 &server_info); 1351 NULL, 1352 &user_info_dc); 1311 1353 1312 1354 if (!NT_STATUS_IS_OK(nt_status)) { … … 1322 1364 } 1323 1365 1324 /* references the server_infointo the session_info */1325 nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx,1326 gensec_security->settings->lp_ctx, server_info, &session_info);1366 /* references the user_info_dc into the session_info */ 1367 nt_status = gensec_generate_session_info(mem_ctx, gensec_security, 1368 user_info_dc, &session_info); 1327 1369 if (!NT_STATUS_IS_OK(nt_status)) { 1328 1370 talloc_free(mem_ctx); … … 1336 1378 } 1337 1379 1380 /* Allow torture tests to check the PAC signatures */ 1381 if (session_info->torture) { 1382 session_info->torture->pac_srv_sig = talloc_steal(session_info->torture, pac_srv_sig); 1383 session_info->torture->pac_kdc_sig = talloc_steal(session_info->torture, pac_kdc_sig); 1384 } 1385 1338 1386 if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) { 1339 1387 DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); 1340 1388 } else { 1341 1389 krb5_error_code ret; 1390 const char *error_string; 1391 1342 1392 DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); 1343 1393 session_info->credentials = cli_credentials_init(session_info); … … 1352 1402 1353 1403 ret = cli_credentials_set_client_gss_creds(session_info->credentials, 1354 gensec_security->event_ctx, 1355 gensec_security->settings->lp_ctx, 1404 gensec_security->settings->lp_ctx, 1356 1405 gensec_gssapi_state->delegated_cred_handle, 1357 CRED_SPECIFIED );1406 CRED_SPECIFIED, &error_string); 1358 1407 if (ret) { 1359 1408 talloc_free(mem_ctx); 1409 DEBUG(2,("Failed to get gss creds: %s\n", error_string)); 1360 1410 return NT_STATUS_NO_MEMORY; 1361 1411 } -
vendor/current/source4/auth/gensec/gensec_gssapi.h
r414 r740 65 65 int gss_exchange_count; 66 66 size_t sig_size; 67 68 const char *target_principal; 67 69 }; 68 70 -
vendor/current/source4/auth/gensec/gensec_krb5.c
r414 r740 27 27 #include "system/kerberos.h" 28 28 #include "auth/kerberos/kerberos.h" 29 #include "librpc/gen_ndr/krb5pac.h"30 29 #include "auth/auth.h" 31 #include "lib/ldb/include/ldb.h"32 #include "auth/auth_sam.h"33 30 #include "lib/socket/socket.h" 31 #include "lib/tsocket/tsocket.h" 34 32 #include "librpc/rpc/dcerpc.h" 35 33 #include "auth/credentials/credentials.h" 36 34 #include "auth/credentials/credentials_krb5.h" 35 #include "auth/kerberos/kerberos_credentials.h" 37 36 #include "auth/gensec/gensec.h" 38 37 #include "auth/gensec/gensec_proto.h" 39 38 #include "param/param.h" 40 #include "auth/session_proto.h"41 39 #include "auth/auth_sam_reply.h" 40 #include "lib/util/util_net.h" 42 41 43 42 enum GENSEC_KRB5_STATE { … … 95 94 struct gensec_krb5_state *gensec_krb5_state; 96 95 struct cli_credentials *creds; 97 const struct socket_address *my_addr, *peer_addr;96 const struct tsocket_address *tlocal_addr, *tremote_addr; 98 97 krb5_address my_krb5_addr, peer_krb5_addr; 99 98 … … 121 120 122 121 if (cli_credentials_get_krb5_context(creds, 123 gensec_security->event_ctx,124 122 gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) { 125 123 talloc_free(gensec_krb5_state); … … 147 145 } 148 146 149 my_addr = gensec_get_my_addr(gensec_security); 150 if (my_addr && my_addr->sockaddr) { 151 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 152 my_addr->sockaddr, &my_krb5_addr); 147 tlocal_addr = gensec_get_local_address(gensec_security); 148 if (tlocal_addr) { 149 ssize_t socklen; 150 struct sockaddr_storage ss; 151 152 socklen = tsocket_address_bsd_sockaddr(tlocal_addr, 153 (struct sockaddr *) &ss, 154 sizeof(struct sockaddr_storage)); 155 if (socklen < 0) { 156 talloc_free(gensec_krb5_state); 157 return NT_STATUS_INTERNAL_ERROR; 158 } 159 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 160 (const struct sockaddr *) &ss, &my_krb5_addr); 153 161 if (ret) { 154 162 DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", … … 160 168 } 161 169 162 peer_addr = gensec_get_peer_addr(gensec_security); 163 if (peer_addr && peer_addr->sockaddr) { 164 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 165 peer_addr->sockaddr, &peer_krb5_addr); 170 tremote_addr = gensec_get_remote_address(gensec_security); 171 if (tremote_addr) { 172 ssize_t socklen; 173 struct sockaddr_storage ss; 174 175 socklen = tsocket_address_bsd_sockaddr(tremote_addr, 176 (struct sockaddr *) &ss, 177 sizeof(struct sockaddr_storage)); 178 if (socklen < 0) { 179 talloc_free(gensec_krb5_state); 180 return NT_STATUS_INTERNAL_ERROR; 181 } 182 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, 183 (const struct sockaddr *) &ss, &peer_krb5_addr); 166 184 if (ret) { 167 185 DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", … … 175 193 ret = krb5_auth_con_setaddrs(gensec_krb5_state->smb_krb5_context->krb5_context, 176 194 gensec_krb5_state->auth_context, 177 my_addr ? &my_krb5_addr : NULL,178 peer_addr ? &peer_krb5_addr : NULL);195 tlocal_addr ? &my_krb5_addr : NULL, 196 tremote_addr ? &peer_krb5_addr : NULL); 179 197 if (ret) { 180 198 DEBUG(1,("gensec_krb5_start: krb5_auth_con_setaddrs failed (%s)\n", … … 221 239 struct ccache_container *ccache_container; 222 240 const char *hostname; 223 241 const char *error_string; 224 242 const char *principal; 225 243 krb5_data in_data; 244 struct tevent_context *previous_ev; 226 245 227 246 hostname = gensec_get_target_hostname(gensec_security); … … 264 283 ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), 265 284 gensec_security->event_ctx, 266 gensec_security->settings->lp_ctx, &ccache_container );285 gensec_security->settings->lp_ctx, &ccache_container, &error_string); 267 286 switch (ret) { 268 287 case 0: 269 288 break; 270 289 case KRB5KDC_ERR_PREAUTH_FAILED: 290 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: 271 291 return NT_STATUS_LOGON_FAILURE; 272 292 case KRB5_KDC_UNREACH: 273 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal)); 293 DEBUG(3, ("Cannot reach a KDC we require to contact %s: %s\n", principal, error_string)); 294 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 295 case KRB5_CC_NOTFOUND: 296 case KRB5_CC_END: 297 DEBUG(3, ("Error preparing credentials we require to contact %s : %s\n", principal, error_string)); 274 298 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */ 275 299 default: 276 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_ message(ret)));300 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_string)); 277 301 return NT_STATUS_UNSUCCESSFUL; 278 302 } 279 303 in_data.length = 0; 280 304 281 if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { 305 /* Do this every time, in case we have weird recursive issues here */ 306 ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev); 307 if (ret != 0) { 308 DEBUG(1, ("gensec_krb5_start: Setting event context failed\n")); 309 return NT_STATUS_NO_MEMORY; 310 } 311 if (principal) { 282 312 krb5_principal target_principal; 283 313 ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal, … … 302 332 &gensec_krb5_state->enc_ticket); 303 333 } 334 335 smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx); 336 304 337 switch (ret) { 305 338 case 0: … … 459 492 struct keytab_container *keytab; 460 493 krb5_principal server_in_keytab; 494 const char *error_string; 495 enum credentials_obtained obtained; 461 496 462 497 if (!in.data) { … … 466 501 /* Grab the keytab, however generated */ 467 502 ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security), 468 gensec_security->event_ctx,469 503 gensec_security->settings->lp_ctx, &keytab); 470 504 if (ret) { … … 475 509 ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security), 476 510 gensec_krb5_state->smb_krb5_context, 477 &server_in_keytab );511 &server_in_keytab, &obtained, &error_string); 478 512 479 513 if (ret) { 514 DEBUG(2,("Failed to make credentials from principal: %s\n", error_string)); 480 515 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 481 516 } … … 569 604 struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; 570 605 krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; 571 struct auth_ serversupplied_info *server_info= NULL;606 struct auth_user_info_dc *user_info_dc = NULL; 572 607 struct auth_session_info *session_info = NULL; 573 608 struct PAC_LOGON_INFO *logon_info; … … 601 636 smb_get_krb5_error_message(context, 602 637 ret, mem_ctx))); 638 krb5_free_principal(context, client_principal); 603 639 talloc_free(mem_ctx); 604 640 return NT_STATUS_NO_MEMORY; … … 614 650 smb_get_krb5_error_message(context, 615 651 ret, mem_ctx))); 652 free(principal_string); 616 653 krb5_free_principal(context, client_principal); 617 free(principal_string);654 talloc_free(mem_ctx); 618 655 return NT_STATUS_ACCESS_DENIED; 619 656 } else if (ret) { … … 627 664 principal_string, smb_get_krb5_error_message(context, 628 665 ret, mem_ctx))); 629 nt_status = gensec_security->auth_context->get_ server_info_principal(mem_ctx,666 nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx, 630 667 gensec_security->auth_context, 631 668 principal_string, 632 &server_info);669 NULL, &user_info_dc); 633 670 if (!NT_STATUS_IS_OK(nt_status)) { 671 free(principal_string); 672 krb5_free_principal(context, client_principal); 634 673 talloc_free(mem_ctx); 635 674 return nt_status; … … 638 677 DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n", 639 678 principal_string)); 679 free(principal_string); 680 krb5_free_principal(context, client_principal); 681 talloc_free(mem_ctx); 640 682 return NT_STATUS_ACCESS_DENIED; 641 }642 643 krb5_free_principal(context, client_principal);644 free(principal_string);645 646 if (!NT_STATUS_IS_OK(nt_status)) {647 talloc_free(mem_ctx);648 return nt_status;649 683 } 650 684 } else { 651 685 /* Found pac */ 652 686 union netr_Validation validation; 653 free(principal_string);654 687 655 688 pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length); 656 689 if (!pac.data) { 690 free(principal_string); 657 691 krb5_free_principal(context, client_principal); 658 692 talloc_free(mem_ctx); … … 662 696 /* decode and verify the pac */ 663 697 nt_status = kerberos_pac_logon_info(gensec_krb5_state, 664 gensec_security->settings->iconv_convenience,665 698 &logon_info, pac, 666 699 gensec_krb5_state->smb_krb5_context->krb5_context, … … 668 701 client_principal, 669 702 gensec_krb5_state->ticket->ticket.authtime, NULL); 670 krb5_free_principal(context, client_principal);671 703 672 704 if (!NT_STATUS_IS_OK(nt_status)) { 705 free(principal_string); 706 krb5_free_principal(context, client_principal); 673 707 talloc_free(mem_ctx); 674 708 return nt_status; … … 676 710 677 711 validation.sam3 = &logon_info->info3; 678 nt_status = make_ server_info_netlogon_validation(mem_ctx,712 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 679 713 NULL, 680 714 3, &validation, 681 & server_info);715 &user_info_dc); 682 716 if (!NT_STATUS_IS_OK(nt_status)) { 717 free(principal_string); 718 krb5_free_principal(context, client_principal); 683 719 talloc_free(mem_ctx); 684 720 return nt_status; … … 686 722 } 687 723 688 /* references the server_info into the session_info */ 689 nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info); 724 free(principal_string); 725 krb5_free_principal(context, client_principal); 726 727 /* references the user_info_dc into the session_info */ 728 nt_status = gensec_generate_session_info(mem_ctx, gensec_security, user_info_dc, &session_info); 690 729 691 730 if (!NT_STATUS_IS_OK(nt_status)) { -
vendor/current/source4/auth/gensec/pygensec.c
r414 r740 17 17 */ 18 18 19 #include <Python.h> 19 20 #include "includes.h" 20 #include <Python.h> 21 #include "param/param.h" 21 #include "param/pyparam.h" 22 22 #include "auth/gensec/gensec.h" 23 #include "auth/credentials/pycredentials.h" 23 24 #include "libcli/util/pyerrors.h" 24 #include "pytalloc.h" 25 #include "scripting/python/modules.h" 26 #include "lib/talloc/pytalloc.h" 25 27 #include <tevent.h> 26 27 #ifndef Py_RETURN_NONE 28 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 29 #endif 28 #include "librpc/rpc/pyrpc_util.h" 30 29 31 30 static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args) … … 38 37 return NULL; 39 38 40 security = (struct gensec_security *)py_talloc_get_ptr(self);39 security = py_talloc_get_type(self, struct gensec_security); 41 40 42 41 name = gensec_get_name_by_authtype(security, type); … … 47 46 } 48 47 49 static struct gensec_settings *settings_from_object(PyObject *object) 50 { 51 return NULL; /* FIXME */ 48 static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object) 49 { 50 struct gensec_settings *s; 51 PyObject *py_hostname, *py_lp_ctx; 52 53 if (!PyDict_Check(object)) { 54 PyErr_SetString(PyExc_ValueError, "settings should be a dictionary"); 55 return NULL; 56 } 57 58 s = talloc_zero(mem_ctx, struct gensec_settings); 59 if (!s) return NULL; 60 61 py_hostname = PyDict_GetItemString(object, "target_hostname"); 62 if (!py_hostname) { 63 PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found"); 64 return NULL; 65 } 66 67 py_lp_ctx = PyDict_GetItemString(object, "lp_ctx"); 68 if (!py_lp_ctx) { 69 PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found"); 70 return NULL; 71 } 72 73 s->target_hostname = PyString_AsString(py_hostname); 74 s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx); 75 return s; 52 76 } 53 77 … … 60 84 PyObject *py_settings; 61 85 struct tevent_context *ev; 62 63 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_settings)) 64 return NULL; 65 66 settings = settings_from_object(py_settings); 67 if (settings == NULL) 68 return NULL; 69 86 struct gensec_security *gensec; 87 88 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings)) 89 return NULL; 90 70 91 self = (py_talloc_Object*)type->tp_alloc(type, 0); 71 92 if (self == NULL) { … … 78 99 return NULL; 79 100 } 101 102 if (py_settings != Py_None) { 103 settings = settings_from_object(self->talloc_ctx, py_settings); 104 if (settings == NULL) { 105 PyObject_DEL(self); 106 return NULL; 107 } 108 } else { 109 settings = talloc_zero(self->talloc_ctx, struct gensec_settings); 110 if (settings == NULL) { 111 PyObject_DEL(self); 112 return NULL; 113 } 114 115 settings->lp_ctx = loadparm_init_global(true); 116 } 117 80 118 ev = tevent_context_init(self->talloc_ctx); 81 119 if (ev == NULL) { … … 84 122 return NULL; 85 123 } 86 status = gensec_client_start(self->talloc_ctx, 87 (struct gensec_security **)&self->ptr, ev, settings);124 125 status = gensec_init(settings->lp_ctx); 88 126 if (!NT_STATUS_IS_OK(status)) { 89 127 PyErr_SetNTSTATUS(status); … … 91 129 return NULL; 92 130 } 131 132 status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings); 133 if (!NT_STATUS_IS_OK(status)) { 134 PyErr_SetNTSTATUS(status); 135 PyObject_DEL(self); 136 return NULL; 137 } 138 139 self->ptr = gensec; 140 93 141 return (PyObject *)self; 94 142 } 95 143 144 static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs) 145 { 146 NTSTATUS status; 147 py_talloc_Object *self; 148 struct gensec_settings *settings = NULL; 149 const char *kwnames[] = { "settings", "auth_context", NULL }; 150 PyObject *py_settings = Py_None; 151 PyObject *py_auth_context = Py_None; 152 struct tevent_context *ev; 153 struct gensec_security *gensec; 154 struct auth_context *auth_context = NULL; 155 156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context)) 157 return NULL; 158 159 self = (py_talloc_Object*)type->tp_alloc(type, 0); 160 if (self == NULL) { 161 PyErr_NoMemory(); 162 return NULL; 163 } 164 self->talloc_ctx = talloc_new(NULL); 165 if (self->talloc_ctx == NULL) { 166 PyErr_NoMemory(); 167 return NULL; 168 } 169 170 if (py_settings != Py_None) { 171 settings = settings_from_object(self->talloc_ctx, py_settings); 172 if (settings == NULL) { 173 PyObject_DEL(self); 174 return NULL; 175 } 176 } else { 177 settings = talloc_zero(self->talloc_ctx, struct gensec_settings); 178 if (settings == NULL) { 179 PyObject_DEL(self); 180 return NULL; 181 } 182 183 settings->lp_ctx = loadparm_init_global(true); 184 } 185 186 ev = tevent_context_init(self->talloc_ctx); 187 if (ev == NULL) { 188 PyErr_NoMemory(); 189 PyObject_Del(self); 190 return NULL; 191 } 192 193 if (py_auth_context != Py_None) { 194 auth_context = py_talloc_get_type(py_auth_context, struct auth_context); 195 if (!auth_context) { 196 PyErr_Format(PyExc_TypeError, 197 "Expected auth.AuthContext for auth_context argument, got %s", 198 talloc_get_name(py_talloc_get_ptr(py_auth_context))); 199 return NULL; 200 } 201 } 202 203 status = gensec_init(settings->lp_ctx); 204 if (!NT_STATUS_IS_OK(status)) { 205 PyErr_SetNTSTATUS(status); 206 PyObject_DEL(self); 207 return NULL; 208 } 209 210 status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec); 211 if (!NT_STATUS_IS_OK(status)) { 212 PyErr_SetNTSTATUS(status); 213 PyObject_DEL(self); 214 return NULL; 215 } 216 217 self->ptr = gensec; 218 219 return (PyObject *)self; 220 } 221 222 static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args) 223 { 224 PyObject *py_creds = Py_None; 225 struct cli_credentials *creds; 226 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 227 NTSTATUS status; 228 229 if (!PyArg_ParseTuple(args, "O", &py_creds)) 230 return NULL; 231 232 creds = PyCredentials_AsCliCredentials(py_creds); 233 if (!creds) { 234 PyErr_Format(PyExc_TypeError, 235 "Expected samba.credentaials for credentials argument got %s", 236 talloc_get_name(py_talloc_get_ptr(py_creds))); 237 } 238 239 status = gensec_set_credentials(security, creds); 240 if (!NT_STATUS_IS_OK(status)) { 241 PyErr_SetNTSTATUS(status); 242 return NULL; 243 } 244 245 Py_RETURN_NONE; 246 } 247 96 248 static PyObject *py_gensec_session_info(PyObject *self) 97 249 { 98 250 NTSTATUS status; 99 struct gensec_security *security = (struct gensec_security *)py_talloc_get_ptr(self); 251 PyObject *py_session_info; 252 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 100 253 struct auth_session_info *info; 254 if (security->ops == NULL) { 255 PyErr_SetString(PyExc_RuntimeError, "no mechanism selected"); 256 return NULL; 257 } 101 258 status = gensec_session_info(security, &info); 102 259 if (NT_STATUS_IS_ERR(status)) { … … 105 262 } 106 263 107 /* FIXME */ 264 py_session_info = py_return_ndr_struct("samba.auth", "AuthSession", 265 info, info); 266 return py_session_info; 267 } 268 269 static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args) 270 { 271 char *name; 272 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 273 NTSTATUS status; 274 275 if (!PyArg_ParseTuple(args, "s", &name)) 276 return NULL; 277 278 status = gensec_start_mech_by_name(security, name); 279 if (!NT_STATUS_IS_OK(status)) { 280 PyErr_SetNTSTATUS(status); 281 return NULL; 282 } 283 108 284 Py_RETURN_NONE; 285 } 286 287 static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args) 288 { 289 char *sasl_name; 290 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 291 NTSTATUS status; 292 293 if (!PyArg_ParseTuple(args, "s", &sasl_name)) 294 return NULL; 295 296 status = gensec_start_mech_by_sasl_name(security, sasl_name); 297 if (!NT_STATUS_IS_OK(status)) { 298 PyErr_SetNTSTATUS(status); 299 return NULL; 300 } 301 302 Py_RETURN_NONE; 303 } 304 305 static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args) 306 { 307 int authtype, level; 308 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 309 NTSTATUS status; 310 if (!PyArg_ParseTuple(args, "ii", &authtype, &level)) 311 return NULL; 312 313 status = gensec_start_mech_by_authtype(security, authtype, level); 314 if (!NT_STATUS_IS_OK(status)) { 315 PyErr_SetNTSTATUS(status); 316 return NULL; 317 } 318 319 Py_RETURN_NONE; 320 } 321 322 static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args) 323 { 324 int feature; 325 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 326 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 327 if (!PyArg_ParseTuple(args, "i", &feature)) 328 return NULL; 329 330 gensec_want_feature(security, feature); 331 332 Py_RETURN_NONE; 333 } 334 335 static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args) 336 { 337 int feature; 338 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 339 /* This is i (and declared as an int above) by design, as they are handled as an integer in python */ 340 if (!PyArg_ParseTuple(args, "i", &feature)) 341 return NULL; 342 343 if (gensec_have_feature(security, feature)) { 344 return Py_True; 345 } 346 return Py_False; 347 } 348 349 static PyObject *py_gensec_update(PyObject *self, PyObject *args) 350 { 351 NTSTATUS status; 352 TALLOC_CTX *mem_ctx; 353 DATA_BLOB in, out; 354 PyObject *ret, *py_in; 355 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 356 PyObject *finished_processing; 357 358 if (!PyArg_ParseTuple(args, "O", &py_in)) 359 return NULL; 360 361 mem_ctx = talloc_new(NULL); 362 363 if (!PyString_Check(py_in)) { 364 PyErr_Format(PyExc_TypeError, "expected a string"); 365 return NULL; 366 } 367 368 in.data = (uint8_t *)PyString_AsString(py_in); 369 in.length = PyString_Size(py_in); 370 371 status = gensec_update(security, mem_ctx, in, &out); 372 373 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) 374 && !NT_STATUS_IS_OK(status)) { 375 PyErr_SetNTSTATUS(status); 376 talloc_free(mem_ctx); 377 return NULL; 378 } 379 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 380 talloc_free(mem_ctx); 381 382 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 383 finished_processing = Py_False; 384 } else { 385 finished_processing = Py_True; 386 } 387 388 return PyTuple_Pack(2, finished_processing, ret); 389 } 390 391 static PyObject *py_gensec_wrap(PyObject *self, PyObject *args) 392 { 393 NTSTATUS status; 394 395 TALLOC_CTX *mem_ctx; 396 DATA_BLOB in, out; 397 PyObject *ret, *py_in; 398 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 399 400 if (!PyArg_ParseTuple(args, "O", &py_in)) 401 return NULL; 402 403 mem_ctx = talloc_new(NULL); 404 405 if (!PyString_Check(py_in)) { 406 PyErr_Format(PyExc_TypeError, "expected a string"); 407 return NULL; 408 } 409 in.data = (uint8_t *)PyString_AsString(py_in); 410 in.length = PyString_Size(py_in); 411 412 status = gensec_wrap(security, mem_ctx, &in, &out); 413 414 if (!NT_STATUS_IS_OK(status)) { 415 PyErr_SetNTSTATUS(status); 416 talloc_free(mem_ctx); 417 return NULL; 418 } 419 420 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 421 talloc_free(mem_ctx); 422 return ret; 423 } 424 425 static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args) 426 { 427 NTSTATUS status; 428 429 TALLOC_CTX *mem_ctx; 430 DATA_BLOB in, out; 431 PyObject *ret, *py_in; 432 struct gensec_security *security = py_talloc_get_type(self, struct gensec_security); 433 434 if (!PyArg_ParseTuple(args, "O", &py_in)) 435 return NULL; 436 437 mem_ctx = talloc_new(NULL); 438 439 if (!PyString_Check(py_in)) { 440 PyErr_Format(PyExc_TypeError, "expected a string"); 441 return NULL; 442 } 443 444 in.data = (uint8_t *)PyString_AsString(py_in); 445 in.length = PyString_Size(py_in); 446 447 status = gensec_unwrap(security, mem_ctx, &in, &out); 448 449 if (!NT_STATUS_IS_OK(status)) { 450 PyErr_SetNTSTATUS(status); 451 talloc_free(mem_ctx); 452 return NULL; 453 } 454 455 ret = PyString_FromStringAndSize((const char *)out.data, out.length); 456 talloc_free(mem_ctx); 457 return ret; 109 458 } 110 459 … … 112 461 { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 113 462 "S.start_client(settings) -> gensec" }, 114 /* { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 115 "S.start_server(auth_ctx, settings) -> gensec" },*/ 463 { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS, 464 "S.start_server(auth_ctx, settings) -> gensec" }, 465 { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS, 466 "S.start_client(credentials)" }, 116 467 { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS, 117 "S.session_info() -> info" }, 468 "S.session_info() -> info" }, 469 { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS, 470 "S.start_mech_by_name(name)" }, 471 { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS, 472 "S.start_mech_by_sasl_name(name)" }, 473 { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" }, 118 474 { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS, 119 475 "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." }, 476 { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS, 477 "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." }, 478 { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS, 479 "S.have_feature()\n Return True if GENSEC negotiated a particular feature." }, 480 { "update", (PyCFunction)py_gensec_update, METH_VARARGS, 481 "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance. Repeat with new packets until finished is true or exception." }, 482 { "wrap", (PyCFunction)py_gensec_wrap, METH_VARARGS, 483 "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." }, 484 { "unwrap", (PyCFunction)py_gensec_unwrap, METH_VARARGS, 485 "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." }, 486 120 487 { NULL } 121 488 }; … … 126 493 .tp_methods = py_gensec_security_methods, 127 494 .tp_basicsize = sizeof(py_talloc_Object), 128 .tp_dealloc = py_talloc_dealloc,129 495 }; 130 496 497 void initgensec(void); 131 498 void initgensec(void) 132 499 { 133 500 PyObject *m; 501 502 Py_Security.tp_base = PyTalloc_GetObjectType(); 503 if (Py_Security.tp_base == NULL) 504 return; 134 505 135 506 if (PyType_Ready(&Py_Security) < 0) … … 140 511 return; 141 512 513 PyModule_AddObject(m, "FEATURE_SESSION_KEY", PyInt_FromLong(GENSEC_FEATURE_SESSION_KEY)); 514 PyModule_AddObject(m, "FEATURE_SIGN", PyInt_FromLong(GENSEC_FEATURE_SIGN)); 515 PyModule_AddObject(m, "FEATURE_SEAL", PyInt_FromLong(GENSEC_FEATURE_SEAL)); 516 PyModule_AddObject(m, "FEATURE_DCE_STYLE", PyInt_FromLong(GENSEC_FEATURE_DCE_STYLE)); 517 PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES", PyInt_FromLong(GENSEC_FEATURE_ASYNC_REPLIES)); 518 PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE", PyInt_FromLong(GENSEC_FEATURE_DATAGRAM_MODE)); 519 PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyInt_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER)); 520 PyModule_AddObject(m, "FEATURE_NEW_SPNEGO", PyInt_FromLong(GENSEC_FEATURE_NEW_SPNEGO)); 521 142 522 Py_INCREF(&Py_Security); 143 523 PyModule_AddObject(m, "Security", (PyObject *)&Py_Security); -
vendor/current/source4/auth/gensec/schannel.c
r414 r740 28 28 #include "auth/gensec/gensec_proto.h" 29 29 #include "../libcli/auth/schannel.h" 30 #include "auth/gensec/schannel_state.h"31 30 #include "librpc/rpc/dcerpc.h" 32 31 #include "param/param.h" 33 #include "auth/session_proto.h"34 32 35 33 static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size) 36 34 { 37 return 32; 35 struct schannel_state *state = (struct schannel_state *)gensec_security->private_data; 36 uint32_t sig_size; 37 38 sig_size = netsec_outgoing_sig_size(state); 39 40 return sig_size; 38 41 } 39 42 … … 53 56 struct NL_AUTH_MESSAGE bind_schannel_ack; 54 57 struct netlogon_creds_CredentialState *creds; 55 struct ldb_context *schannel_ldb;56 58 const char *workstation; 57 59 const char *domain; 58 uint32_t required_flags;59 60 60 61 *out = data_blob(NULL, 0); … … 91 92 #endif 92 93 93 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, 94 gensec_security->settings->iconv_convenience, &bind_schannel, 94 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel, 95 95 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); 96 96 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 106 106 case GENSEC_SERVER: 107 107 108 required_flags = NL_FLAG_OEM_NETBIOS_COMPUTER_NAME |109 NL_FLAG_OEM_NETBIOS_DOMAIN_NAME;110 111 108 if (state->state != SCHANNEL_STATE_START) { 112 109 /* no third leg on this protocol */ … … 115 112 116 113 /* parse the schannel startup blob */ 117 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, 118 gensec_security->settings->iconv_convenience, 119 &bind_schannel, 114 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel, 120 115 (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE); 121 116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 126 121 } 127 122 128 if (!(required_flags == (bind_schannel.Flags & required_flags))) { 129 return NT_STATUS_INVALID_PARAMETER; 130 } 131 132 workstation = bind_schannel.oem_netbios_computer.a; 133 domain = bind_schannel.oem_netbios_domain.a; 134 135 if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) { 136 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 137 domain, lp_workgroup(gensec_security->settings->lp_ctx))); 138 123 if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_DOMAIN_NAME) { 124 domain = bind_schannel.oem_netbios_domain.a; 125 if (strcasecmp_m(domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)) != 0) { 126 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 127 domain, lpcfg_workgroup(gensec_security->settings->lp_ctx))); 128 return NT_STATUS_LOGON_FAILURE; 129 } 130 } else if (bind_schannel.Flags & NL_FLAG_UTF8_DNS_DOMAIN_NAME) { 131 domain = bind_schannel.utf8_dns_domain.u; 132 if (strcasecmp_m(domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)) != 0) { 133 DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n", 134 domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx))); 135 return NT_STATUS_LOGON_FAILURE; 136 } 137 } else { 138 DEBUG(3, ("Request for schannel to without domain\n")); 139 139 return NT_STATUS_LOGON_FAILURE; 140 140 } 141 141 142 schannel_ldb = schannel_db_connect(out_mem_ctx, gensec_security->event_ctx, 143 gensec_security->settings->lp_ctx); 144 if (!schannel_ldb) { 145 return NT_STATUS_ACCESS_DENIED; 146 } 147 /* pull the session key for this client */ 148 status = schannel_fetch_session_key_ldb(schannel_ldb, 149 out_mem_ctx, workstation, &creds); 150 talloc_free(schannel_ldb); 142 if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME) { 143 workstation = bind_schannel.oem_netbios_computer.a; 144 } else if (bind_schannel.Flags & NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME) { 145 workstation = bind_schannel.utf8_netbios_computer.u; 146 } else { 147 DEBUG(3, ("Request for schannel to without netbios workstation\n")); 148 return NT_STATUS_LOGON_FAILURE; 149 } 150 151 status = schannel_get_creds_state(out_mem_ctx, 152 lpcfg_private_dir(gensec_security->settings->lp_ctx), 153 workstation, &creds); 151 154 if (!NT_STATUS_IS_OK(status)) { 152 155 DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", … … 158 161 } 159 162 160 state->creds = talloc_ reference(state, creds);163 state->creds = talloc_steal(state, creds); 161 164 162 165 bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE; … … 167 170 * - gd */ 168 171 169 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, 170 gensec_security->settings->iconv_convenience, &bind_schannel_ack, 172 ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack, 171 173 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE); 172 174 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 215 217 { 216 218 struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); 217 return auth_anonymous_session_info(state, gensec_security-> event_ctx, gensec_security->settings->lp_ctx, _session_info);219 return auth_anonymous_session_info(state, gensec_security->settings->lp_ctx, _session_info); 218 220 } 219 221 -
vendor/current/source4/auth/gensec/socket.c
r414 r740 78 78 &unwrapped, &wrapped); 79 79 if (!NT_STATUS_IS_OK(nt_status)) { 80 talloc_free(mem_ctx);81 80 return nt_status; 82 81 } -
vendor/current/source4/auth/gensec/spnego.c
r414 r740 29 29 #include "auth/gensec/gensec.h" 30 30 #include "auth/gensec/gensec_proto.h" 31 #include "param/param.h" 31 32 32 33 enum spnego_state_position { … … 420 421 421 422 if (spnego_state->state_position == SPNEGO_SERVER_START) { 422 for (i=0; all_sec && all_sec[i].op; i++) {423 /* optomisitic token */424 if (strcmp(all_sec[i].oid, mechType[0]) == 0) {423 uint32_t j; 424 for (j=0; mechType && mechType[j]; j++) { 425 for (i=0; all_sec && all_sec[i].op; i++) { 425 426 nt_status = gensec_subcontext_start(spnego_state, 426 427 gensec_security, … … 437 438 break; 438 439 } 439 440 441 if (j > 0) { 442 /* no optimistic token */ 443 spnego_state->neg_oid = all_sec[i].oid; 444 *unwrapped_out = data_blob_null; 445 nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED; 446 break; 447 } 448 440 449 nt_status = gensec_update(spnego_state->sub_sec_security, 441 450 out_mem_ctx, … … 456 465 break; 457 466 } 458 } 459 } 460 461 /* Having tried any optomisitc token from the client (if we 467 if (spnego_state->sub_sec_security) { 468 break; 469 } 470 } 471 472 if (!spnego_state->sub_sec_security) { 473 DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n")); 474 return NT_STATUS_INVALID_PARAMETER; 475 } 476 } 477 478 /* Having tried any optimistic token from the client (if we 462 479 * were the server), if we didn't get anywhere, walk our list 463 480 * in our preference order */ … … 495 512 if (spnego_state->state_position != SPNEGO_SERVER_START) { 496 513 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) || 514 NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS) || 515 NT_STATUS_EQUAL(nt_status, NT_STATUS_TIME_DIFFERENCE_AT_DC) || 497 516 NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) { 498 517 /* Pretend we never started it (lets the first run find some incompatible demand) */ … … 566 585 DATA_BLOB unwrapped_out = data_blob(NULL, 0); 567 586 const struct gensec_security_ops_wrapper *all_sec; 568 const char *principal = NULL;569 587 570 588 mechTypes = gensec_security_oids(gensec_security, … … 633 651 634 652 if (spnego_state->state_position == SPNEGO_SERVER_START) { 635 /* server credentials */636 struct cli_credentials *creds = gensec_get_credentials(gensec_security);637 if (creds) {638 principal = cli_credentials_get_principal(creds, out_mem_ctx);639 }640 }641 if (principal) {642 653 spnego_out.negTokenInit.mechListMIC 643 = data_blob_string_const( principal);654 = data_blob_string_const(ADS_IGNORE_PRINCIPAL); 644 655 } else { 645 656 spnego_out.negTokenInit.mechListMIC = null_data_blob; … … 825 836 } 826 837 827 if (spnego.negTokenInit.targetPrincipal) { 838 if (spnego.negTokenInit.targetPrincipal 839 && strcmp(spnego.negTokenInit.targetPrincipal, ADS_IGNORE_PRINCIPAL) != 0) { 828 840 DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal)); 829 gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); 841 if (lpcfg_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { 842 gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal); 843 } 830 844 } 831 845 -
vendor/current/source4/auth/kerberos/kerberos.c
r414 r740 34 34 This version is built to use a keyblock, rather than needing the 35 35 original password. 36 37 The impersonate_principal is the principal if NULL, or the principal to impersonate 38 39 The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) 36 40 */ 37 41 krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 38 krb5_principal principal, krb5_keyblock *keyblock, 39 time_t *expire_time, time_t *kdc_time) 42 krb5_principal principal, krb5_keyblock *keyblock, 43 const char *target_service, 44 krb5_get_init_creds_opt *krb_options, 45 time_t *expire_time, time_t *kdc_time) 40 46 { 41 47 krb5_error_code code = 0; 42 48 krb5_creds my_creds; 43 krb5_get_init_creds_opt *options;44 45 if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {46 return code;47 }48 49 krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);50 49 51 50 if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock, 52 0, NULL,options))) {51 0, target_service, krb_options))) { 53 52 return code; 54 53 } 55 54 56 55 if ((code = krb5_cc_initialize(ctx, cc, principal))) { 57 krb5_get_init_creds_opt_free(ctx, options);58 56 krb5_free_cred_contents(ctx, &my_creds); 59 57 return code; … … 61 59 62 60 if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { 63 krb5_get_init_creds_opt_free(ctx, options);64 61 krb5_free_cred_contents(ctx, &my_creds); 65 62 return code; … … 74 71 } 75 72 76 krb5_get_init_creds_opt_free(ctx, options);77 73 krb5_free_cred_contents(ctx, &my_creds); 78 74 … … 83 79 simulate a kinit, putting the tgt in the given credentials cache. 84 80 Orignally by remus@snapserver.com 81 82 The impersonate_principal is the principal if NULL, or the principal to impersonate 83 84 The target_service defaults to the krbtgt if NULL, but could be kpasswd/realm or the local service (if we are doing s4u2self) 85 85 86 */ 86 87 krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 87 krb5_principal principal, const char *password, 88 time_t *expire_time, time_t *kdc_time) 88 krb5_principal principal, const char *password, 89 krb5_principal impersonate_principal, const char *target_service, 90 krb5_get_init_creds_opt *krb_options, 91 time_t *expire_time, time_t *kdc_time) 89 92 { 90 93 krb5_error_code code = 0; 91 94 krb5_creds my_creds; 92 krb5_get_init_creds_opt *options; 95 krb5_creds *impersonate_creds; 96 krb5_get_creds_opt options; 93 97 94 if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) { 98 /* If we are not impersonating, then get this ticket for the 99 * target service, otherwise a krbtgt, and get the next ticket 100 * for the target */ 101 if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password, 102 NULL, NULL, 103 0, 104 impersonate_principal ? NULL : target_service, 105 krb_options))) { 95 106 return code; 96 107 } 97 108 98 krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);99 100 if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,101 NULL,102 NULL, 0, NULL, options))) {103 return code;104 }105 106 109 if ((code = krb5_cc_initialize(ctx, cc, principal))) { 107 krb5_get_init_creds_opt_free(ctx, options);108 110 krb5_free_cred_contents(ctx, &my_creds); 109 111 return code; … … 111 113 112 114 if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) { 113 krb5_get_init_creds_opt_free(ctx, options);114 115 krb5_free_cred_contents(ctx, &my_creds); 115 116 return code; … … 124 125 } 125 126 126 krb5_get_init_creds_opt_free(ctx, options);127 127 krb5_free_cred_contents(ctx, &my_creds); 128 128 129 if (code == 0 && impersonate_principal) { 130 krb5_principal target_princ; 131 if ((code = krb5_get_creds_opt_alloc(ctx, &options))) { 132 return code; 133 } 134 135 if ((code = krb5_get_creds_opt_set_impersonate(ctx, options, impersonate_principal))) { 136 krb5_get_creds_opt_free(ctx, options); 137 return code; 138 } 139 140 if ((code = krb5_parse_name(ctx, target_service, &target_princ))) { 141 krb5_get_creds_opt_free(ctx, options); 142 return code; 143 } 144 145 if ((code = krb5_principal_set_realm(ctx, target_princ, krb5_principal_get_realm(ctx, principal)))) { 146 krb5_get_creds_opt_free(ctx, options); 147 krb5_free_principal(ctx, target_princ); 148 return code; 149 } 150 151 if ((code = krb5_get_creds(ctx, options, cc, target_princ, &impersonate_creds))) { 152 krb5_free_principal(ctx, target_princ); 153 krb5_get_creds_opt_free(ctx, options); 154 return code; 155 } 156 157 krb5_free_principal(ctx, target_princ); 158 159 code = krb5_cc_store_cred(ctx, cc, impersonate_creds); 160 krb5_get_creds_opt_free(ctx, options); 161 krb5_free_creds(ctx, impersonate_creds); 162 } 163 129 164 return 0; 130 165 } -
vendor/current/source4/auth/kerberos/kerberos.h
r414 r740 24 24 #include "librpc/gen_ndr/krb5pac.h" 25 25 26 struct auth_ serversupplied_info;26 struct auth_user_info_dc; 27 27 struct cli_credentials; 28 28 … … 53 53 #define KRB5_KEY_DATA(k) ((k)->contents) 54 54 #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ 55 56 #define ENC_ALL_TYPES (ENC_CRC32 | ENC_RSA_MD5 | ENC_RC4_HMAC_MD5 | \ 57 ENC_HMAC_SHA1_96_AES128 | ENC_HMAC_SHA1_96_AES256) 55 58 56 59 #ifndef HAVE_KRB5_SET_REAL_TIME … … 89 92 krb5_data *outbuf); 90 93 bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt); 91 int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 92 krb5_principal principal, const char *password, 93 time_t *expire_time, time_t *kdc_time); 94 int kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 95 krb5_principal principal, krb5_keyblock *keyblock, 96 time_t *expire_time, time_t *kdc_time); 94 krb5_error_code kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, 95 krb5_principal principal, const char *password, 96 krb5_principal impersonate_principal, const char *target_service, 97 krb5_get_init_creds_opt *krb_options, 98 time_t *expire_time, time_t *kdc_time); 99 krb5_error_code kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, 100 krb5_principal principal, krb5_keyblock *keyblock, 101 const char *target_service, 102 krb5_get_init_creds_opt *krb_options, 103 time_t *expire_time, time_t *kdc_time); 97 104 krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, 98 105 krb5_principal host_princ, … … 103 110 krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry); 104 111 char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx); 105 krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,106 struct cli_credentials *credentials,107 struct smb_krb5_context *smb_krb5_context,108 krb5_ccache ccache);109 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx,110 struct cli_credentials *credentials,111 struct smb_krb5_context *smb_krb5_context,112 krb5_principal *princ);113 112 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, 114 struct smb_iconv_convenience *iconv_convenience,115 113 struct PAC_DATA **pac_data_out, 116 114 DATA_BLOB blob, … … 122 120 krb5_error_code *k5ret); 123 121 NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx, 124 struct smb_iconv_convenience *iconv_convenience,125 122 struct PAC_LOGON_INFO **logon_info, 126 123 DATA_BLOB blob, … … 132 129 krb5_error_code *k5ret); 133 130 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx, 134 struct smb_iconv_convenience *iconv_convenience,135 131 struct PAC_DATA *pac_data, 136 132 krb5_context context, … … 139 135 DATA_BLOB *pac); 140 136 krb5_error_code kerberos_create_pac(TALLOC_CTX *mem_ctx, 141 struct smb_iconv_convenience *iconv_convenience, 142 struct auth_serversupplied_info *server_info, 137 struct auth_user_info_dc *user_info_dc, 143 138 krb5_context context, 144 139 const krb5_keyblock *krbtgt_keyblock, … … 148 143 DATA_BLOB *pac); 149 144 struct loadparm_context; 145 struct ldb_message; 146 struct ldb_context; 147 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum); 148 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */ 149 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap); 150 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, 151 struct smb_krb5_context *smb_krb5_context, 152 struct ldb_context *ldb, 153 struct ldb_message *msg, 154 bool delete_all_kvno, 155 const char **error_string); 150 156 151 157 #include "auth/kerberos/proto.h" -
vendor/current/source4/auth/kerberos/kerberos_pac.c
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 4 4 Create and parse the krb5 PAC 5 5 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005,2008 7 7 Copyright (C) Andrew Tridgell 2001 … … 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of … … 19 19 GNU General Public License for more details. 20 20 21 21 22 22 You should have received a copy of the GNU General Public License 23 23 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 29 29 #include "auth/kerberos/kerberos.h" 30 30 #include "librpc/gen_ndr/ndr_krb5pac.h" 31 #include "lib/ldb/include/ldb.h"31 #include <ldb.h> 32 32 #include "auth/auth_sam_reply.h" 33 33 34 krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, 34 krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx, 35 35 DATA_BLOB pac_data, 36 36 struct PAC_SIGNATURE_DATA *sig, … … 51 51 &crypto); 52 52 if (ret) { 53 DEBUG(0,("krb5_crypto_init() failed: %s\n", 53 DEBUG(0,("krb5_crypto_init() failed: %s\n", 54 54 smb_get_krb5_error_message(context, ret, mem_ctx))); 55 55 return ret; … … 67 67 68 68 NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, 69 struct smb_iconv_convenience *iconv_convenience,70 69 struct PAC_DATA **pac_data_out, 71 70 DATA_BLOB blob, … … 95 94 NTTIME tgs_authtime_nttime; 96 95 krb5_principal client_principal_pac; 97 int i;96 uint32_t i; 98 97 99 98 krb5_clear_error_message(context); … … 114 113 } 115 114 116 ndr_err = ndr_pull_struct_blob(&blob, pac_data, 117 iconv_convenience, pac_data, 118 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); 115 ndr_err = ndr_pull_struct_blob(&blob, pac_data, 116 pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); 119 117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 120 118 status = ndr_map_error2ntstatus(ndr_err); … … 130 128 } 131 129 132 ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw, 133 iconv_convenience,pac_data_raw,130 ndr_err = ndr_pull_struct_blob(&blob, pac_data_raw, 131 pac_data_raw, 134 132 (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA_RAW); 135 133 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 211 209 212 210 /* We find the data blobs above, now we parse them to get at the exact portion we should zero */ 213 ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, 214 iconv_convenience,kdc_sig_wipe,211 ndr_err = ndr_pull_struct_blob(kdc_sig_blob, kdc_sig_wipe, 212 kdc_sig_wipe, 215 213 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 216 214 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 220 218 return status; 221 219 } 222 223 ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, 224 iconv_convenience,srv_sig_wipe,220 221 ndr_err = ndr_pull_struct_blob(srv_sig_blob, srv_sig_wipe, 222 srv_sig_wipe, 225 223 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 226 224 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 234 232 memset(kdc_sig_wipe->signature.data, '\0', kdc_sig_wipe->signature.length); 235 233 memset(srv_sig_wipe->signature.data, '\0', srv_sig_wipe->signature.length); 236 234 237 235 /* and reencode, back into the same place it came from */ 238 ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, 239 iconv_convenience, 236 ndr_err = ndr_push_struct_blob(kdc_sig_blob, pac_data_raw, 240 237 kdc_sig_wipe, 241 238 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); … … 246 243 return status; 247 244 } 248 ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, 249 iconv_convenience, 245 ndr_err = ndr_push_struct_blob(srv_sig_blob, pac_data_raw, 250 246 srv_sig_wipe, 251 247 (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA); … … 258 254 259 255 /* push out the whole structure, but now with zero'ed signatures */ 260 ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, 261 iconv_convenience, 256 ndr_err = ndr_push_struct_blob(&modified_pac_blob, pac_data_raw, 262 257 pac_data_raw, 263 258 (ndr_push_flags_fn_t)ndr_push_PAC_DATA_RAW); … … 270 265 271 266 /* verify by service_key */ 272 ret = check_pac_checksum(mem_ctx, 273 modified_pac_blob, srv_sig_ptr, 274 context, 267 ret = check_pac_checksum(mem_ctx, 268 modified_pac_blob, srv_sig_ptr, 269 context, 275 270 service_keyblock); 276 271 if (ret) { … … 284 279 285 280 if (krbtgt_keyblock) { 286 ret = check_pac_checksum(mem_ctx, 287 srv_sig_ptr->signature, kdc_sig_ptr, 281 ret = check_pac_checksum(mem_ctx, 282 srv_sig_ptr->signature, kdc_sig_ptr, 288 283 context, krbtgt_keyblock); 289 284 if (ret) { … … 307 302 } 308 303 309 ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM, 304 ret = krb5_parse_name_flags(context, logon_name->account_name, KRB5_PRINCIPAL_PARSE_NO_REALM, 310 305 &client_principal_pac); 311 306 if (ret) { 312 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 313 logon_name->account_name, 307 DEBUG(2, ("Could not parse name from incoming PAC: [%s]: %s\n", 308 logon_name->account_name, 314 309 smb_get_krb5_error_message(context, ret, mem_ctx))); 315 310 if (k5ret) { … … 320 315 321 316 if (!krb5_principal_compare_any_realm(context, client_principal, client_principal_pac)) { 322 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", 317 DEBUG(2, ("Name in PAC [%s] does not match principal name in ticket\n", 323 318 logon_name->account_name)); 319 krb5_free_principal(context, client_principal_pac); 324 320 return NT_STATUS_ACCESS_DENIED; 325 321 } 326 322 323 krb5_free_principal(context, client_principal_pac); 324 327 325 #if 0 328 if (strcasecmp(logon_info->info3.base.account_name.string, 326 if (strcasecmp(logon_info->info3.base.account_name.string, 329 327 "Administrator")== 0) { 330 328 file_save("tmp_pac_data-admin.dat",blob.data,blob.length); … … 333 331 334 332 DEBUG(3,("Found account name from PAC: %s [%s]\n", 335 logon_info->info3.base.account_name.string, 333 logon_info->info3.base.account_name.string, 336 334 logon_info->info3.base.full_name.string)); 337 335 *pac_data_out = pac_data; … … 341 339 342 340 _PUBLIC_ NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx, 343 struct smb_iconv_convenience *iconv_convenience,344 341 struct PAC_LOGON_INFO **logon_info, 345 342 DATA_BLOB blob, … … 348 345 const krb5_keyblock *service_keyblock, 349 346 krb5_const_principal client_principal, 350 time_t tgs_authtime, 347 time_t tgs_authtime, 351 348 krb5_error_code *k5ret) 352 349 { … … 354 351 struct PAC_DATA *pac_data; 355 352 int i; 356 nt_status = kerberos_decode_pac(mem_ctx, 357 iconv_convenience, 353 nt_status = kerberos_decode_pac(mem_ctx, 358 354 &pac_data, 359 355 blob, … … 361 357 krbtgt_keyblock, 362 358 service_keyblock, 363 client_principal, 359 client_principal, 364 360 tgs_authtime, 365 361 k5ret); … … 373 369 continue; 374 370 } 375 *logon_info = pac_data->buffers[i].info->logon_info.info; 371 *logon_info = pac_data->buffers[i].info->logon_info.info; 376 372 } 377 373 if (!*logon_info) { … … 381 377 } 382 378 383 static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx, 379 static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx, 384 380 DATA_BLOB *pac_data, 385 381 struct PAC_SIGNATURE_DATA *sig, … … 409 405 &cksum); 410 406 if (ret) { 411 DEBUG(2, ("PAC Verification failed: %s\n", 407 DEBUG(2, ("PAC Verification failed: %s\n", 412 408 smb_get_krb5_error_message(context, ret, mem_ctx))); 413 409 } … … 427 423 428 424 krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx, 429 struct smb_iconv_convenience *iconv_convenience,430 425 struct PAC_DATA *pac_data, 431 426 krb5_context context, 432 427 const krb5_keyblock *krbtgt_keyblock, 433 428 const krb5_keyblock *service_keyblock, 434 DATA_BLOB *pac) 429 DATA_BLOB *pac) 435 430 { 436 431 NTSTATUS nt_status; … … 448 443 continue; 449 444 } 450 kdc_checksum = &pac_data->buffers[i].info->kdc_cksum, 445 kdc_checksum = &pac_data->buffers[i].info->kdc_cksum, 451 446 ret = make_pac_checksum(mem_ctx, &zero_blob, 452 kdc_checksum, 447 kdc_checksum, 453 448 context, krbtgt_keyblock); 454 449 if (ret) { 455 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 450 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 456 451 smb_get_krb5_error_message(context, ret, mem_ctx))); 457 452 talloc_free(pac_data); … … 459 454 } 460 455 } 461 456 462 457 for (i=0; i < pac_data->num_buffers; i++) { 463 458 if (pac_data->buffers[i].type != PAC_TYPE_SRV_CHECKSUM) { 464 459 continue; 465 460 } 466 srv_checksum = &pac_data->buffers[i].info->srv_cksum; 467 ret = make_pac_checksum(mem_ctx, &zero_blob, 468 srv_checksum, 461 srv_checksum = &pac_data->buffers[i].info->srv_cksum; 462 ret = make_pac_checksum(mem_ctx, &zero_blob, 463 srv_checksum, 469 464 context, service_keyblock); 470 465 if (ret) { 471 DEBUG(2, ("making service PAC checksum failed: %s\n", 466 DEBUG(2, ("making service PAC checksum failed: %s\n", 472 467 smb_get_krb5_error_message(context, ret, mem_ctx))); 473 468 talloc_free(pac_data); … … 489 484 memset(srv_checksum->signature.data, '\0', srv_checksum->signature.length); 490 485 491 ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 492 iconv_convenience, 486 ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 493 487 pac_data, 494 488 (ndr_push_flags_fn_t)ndr_push_PAC_DATA); … … 507 501 ret = make_pac_checksum(mem_ctx, &srv_checksum->signature, kdc_checksum, context, krbtgt_keyblock); 508 502 if (ret) { 509 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 503 DEBUG(2, ("making krbtgt PAC checksum failed: %s\n", 510 504 smb_get_krb5_error_message(context, ret, mem_ctx))); 511 505 talloc_free(pac_data); … … 514 508 515 509 /* And push it out again, this time to the world. This relies on determanistic pointer values */ 516 ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 517 iconv_convenience, 510 ndr_err = ndr_push_struct_blob(&tmp_blob, mem_ctx, 518 511 pac_data, 519 512 (ndr_push_flags_fn_t)ndr_push_PAC_DATA); … … 532 525 533 526 krb5_error_code kerberos_create_pac(TALLOC_CTX *mem_ctx, 534 struct smb_iconv_convenience *iconv_convenience, 535 struct auth_serversupplied_info *server_info, 527 struct auth_user_info_dc *user_info_dc, 536 528 krb5_context context, 537 529 const krb5_keyblock *krbtgt_keyblock, … … 553 545 554 546 char *name; 555 547 556 548 enum { 557 549 PAC_BUF_LOGON_INFO = 0, … … 569 561 pac_data->version = 0; 570 562 571 pac_data->buffers = talloc_array(pac_data, 563 pac_data->buffers = talloc_array(pac_data, 572 564 struct PAC_BUFFER, 573 565 pac_data->num_buffers); … … 621 613 return ENOMEM; 622 614 } 623 nt_status = auth_convert_ server_info_saminfo3(LOGON_INFO, server_info, &sam3);615 nt_status = auth_convert_user_info_dc_saminfo3(LOGON_INFO, user_info_dc, &sam3); 624 616 if (!NT_STATUS_IS_OK(nt_status)) { 625 617 DEBUG(1, ("Getting Samba info failed: %s\n", nt_errstr(nt_status))); … … 631 623 LOGON_INFO->info3 = *sam3; 632 624 633 ret = krb5_unparse_name_flags(context, client_principal, 625 ret = krb5_unparse_name_flags(context, client_principal, 634 626 KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name); 635 627 if (ret) { … … 644 636 unix_to_nt_time(&LOGON_NAME->logon_time, tgs_authtime); 645 637 646 ret = kerberos_encode_pac(mem_ctx, 647 iconv_convenience, 648 pac_data, 638 ret = kerberos_encode_pac(mem_ctx, 639 pac_data, 649 640 context, 650 641 krbtgt_keyblock, … … 655 646 } 656 647 657 krb5_error_code kerberos_pac_to_server_info(TALLOC_CTX *mem_ctx, 658 struct smb_iconv_convenience *iconv_convenience, 659 krb5_pac pac, 660 krb5_context context, 661 struct auth_serversupplied_info **server_info) 648 krb5_error_code kerberos_pac_to_user_info_dc(TALLOC_CTX *mem_ctx, 649 krb5_pac pac, 650 krb5_context context, 651 struct auth_user_info_dc **user_info_dc, 652 struct PAC_SIGNATURE_DATA *pac_srv_sig, 653 struct PAC_SIGNATURE_DATA *pac_kdc_sig) 662 654 { 663 655 NTSTATUS nt_status; … … 669 661 670 662 union PAC_INFO info; 671 union netr_Validation validation; 672 struct auth_serversupplied_info *server_info_out; 663 struct auth_user_info_dc *user_info_dc_out; 673 664 674 665 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); … … 686 677 pac_logon_info_in = data_blob_const(k5pac_logon_info_in.data, k5pac_logon_info_in.length); 687 678 688 ndr_err = ndr_pull_union_blob(&pac_logon_info_in, tmp_ctx, iconv_convenience,&info,679 ndr_err = ndr_pull_union_blob(&pac_logon_info_in, tmp_ctx, &info, 689 680 PAC_TYPE_LOGON_INFO, 690 681 (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO); … … 698 689 699 690 /* Pull this right into the normal auth sysstem structures */ 700 validation.sam3 = &info.logon_info.info->info3; 701 nt_status = make_server_info_netlogon_validation(mem_ctx, 702 "", 703 3, &validation, 704 &server_info_out); 691 nt_status = make_user_info_dc_pac(mem_ctx, 692 info.logon_info.info, 693 &user_info_dc_out); 705 694 if (!NT_STATUS_IS_OK(nt_status)) { 706 695 talloc_free(tmp_ctx); 707 696 return EINVAL; 708 697 } 709 710 ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_SRV_CHECKSUM, &k5pac_srv_checksum_in); 711 if (ret != 0) { 712 talloc_free(tmp_ctx); 713 return ret; 714 } 715 716 pac_srv_checksum_in = data_blob_const(k5pac_srv_checksum_in.data, k5pac_srv_checksum_in.length); 717 718 ndr_err = ndr_pull_struct_blob(&pac_srv_checksum_in, server_info_out, 719 iconv_convenience, &server_info_out->pac_srv_sig, 720 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 721 krb5_data_free(&k5pac_srv_checksum_in); 722 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 723 nt_status = ndr_map_error2ntstatus(ndr_err); 724 DEBUG(0,("can't parse the KDC signature: %s\n", 725 nt_errstr(nt_status))); 726 return EINVAL; 727 } 728 729 ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_KDC_CHECKSUM, &k5pac_kdc_checksum_in); 730 if (ret != 0) { 731 talloc_free(tmp_ctx); 732 return ret; 733 } 734 735 pac_kdc_checksum_in = data_blob_const(k5pac_kdc_checksum_in.data, k5pac_kdc_checksum_in.length); 736 737 ndr_err = ndr_pull_struct_blob(&pac_kdc_checksum_in, server_info_out, 738 iconv_convenience, &server_info_out->pac_kdc_sig, 739 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 740 krb5_data_free(&k5pac_kdc_checksum_in); 741 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 742 nt_status = ndr_map_error2ntstatus(ndr_err); 743 DEBUG(0,("can't parse the KDC signature: %s\n", 744 nt_errstr(nt_status))); 745 return EINVAL; 746 } 747 748 *server_info = server_info_out; 749 698 699 if (pac_srv_sig) { 700 ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_SRV_CHECKSUM, &k5pac_srv_checksum_in); 701 if (ret != 0) { 702 talloc_free(tmp_ctx); 703 return ret; 704 } 705 706 pac_srv_checksum_in = data_blob_const(k5pac_srv_checksum_in.data, k5pac_srv_checksum_in.length); 707 708 ndr_err = ndr_pull_struct_blob(&pac_srv_checksum_in, pac_srv_sig, 709 pac_srv_sig, 710 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 711 krb5_data_free(&k5pac_srv_checksum_in); 712 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 713 nt_status = ndr_map_error2ntstatus(ndr_err); 714 DEBUG(0,("can't parse the KDC signature: %s\n", 715 nt_errstr(nt_status))); 716 return EINVAL; 717 } 718 } 719 720 if (pac_kdc_sig) { 721 ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_KDC_CHECKSUM, &k5pac_kdc_checksum_in); 722 if (ret != 0) { 723 talloc_free(tmp_ctx); 724 return ret; 725 } 726 727 pac_kdc_checksum_in = data_blob_const(k5pac_kdc_checksum_in.data, k5pac_kdc_checksum_in.length); 728 729 ndr_err = ndr_pull_struct_blob(&pac_kdc_checksum_in, pac_kdc_sig, 730 pac_kdc_sig, 731 (ndr_pull_flags_fn_t)ndr_pull_PAC_SIGNATURE_DATA); 732 krb5_data_free(&k5pac_kdc_checksum_in); 733 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 734 nt_status = ndr_map_error2ntstatus(ndr_err); 735 DEBUG(0,("can't parse the KDC signature: %s\n", 736 nt_errstr(nt_status))); 737 return EINVAL; 738 } 739 } 740 *user_info_dc = user_info_dc_out; 741 750 742 return 0; 751 743 } 752 744 753 745 754 NTSTATUS kerberos_pac_blob_to_server_info(TALLOC_CTX *mem_ctx, 755 struct smb_iconv_convenience *iconv_convenience, 756 DATA_BLOB pac_blob, 757 krb5_context context, 758 struct auth_serversupplied_info **server_info) 746 NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx, 747 DATA_BLOB pac_blob, 748 krb5_context context, 749 struct auth_user_info_dc **user_info_dc, 750 struct PAC_SIGNATURE_DATA *pac_srv_sig, 751 struct PAC_SIGNATURE_DATA *pac_kdc_sig) 759 752 { 760 753 krb5_error_code ret; 761 754 krb5_pac pac; 762 ret = krb5_pac_parse(context, 763 pac_blob.data, pac_blob.length, 755 ret = krb5_pac_parse(context, 756 pac_blob.data, pac_blob.length, 764 757 &pac); 765 758 if (ret) { … … 768 761 769 762 770 ret = kerberos_pac_to_ server_info(mem_ctx, iconv_convenience, pac, context, server_info);763 ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig); 771 764 krb5_pac_free(context, pac); 772 765 if (ret) { -
vendor/current/source4/auth/kerberos/kerberos_util.c
r414 r740 27 27 #include "auth/credentials/credentials_proto.h" 28 28 #include "auth/credentials/credentials_krb5.h" 29 #include "auth/kerberos/kerberos_credentials.h" 30 #include "auth/kerberos/kerberos_util.h" 31 #include <ldb.h> 32 #include "param/secrets.h" 29 33 30 34 struct principal_container { 31 35 struct smb_krb5_context *smb_krb5_context; 32 36 krb5_principal principal; 37 const char *string_form; /* Optional */ 33 38 }; 34 39 … … 41 46 } 42 47 43 static krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx, 44 struct cli_credentials *machine_account, 45 struct smb_krb5_context *smb_krb5_context, 46 krb5_principal *salt_princ) 47 { 48 49 static krb5_error_code parse_principal(TALLOC_CTX *parent_ctx, 50 const char *princ_string, 51 struct smb_krb5_context *smb_krb5_context, 52 krb5_principal *princ, 53 const char **error_string) 54 { 55 int ret; 56 struct principal_container *mem_ctx; 57 if (princ_string == NULL) { 58 *princ = NULL; 59 return 0; 60 } 61 62 ret = krb5_parse_name(smb_krb5_context->krb5_context, 63 princ_string, princ); 64 65 if (ret) { 66 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); 67 return ret; 68 } 69 70 mem_ctx = talloc(parent_ctx, struct principal_container); 71 if (!mem_ctx) { 72 (*error_string) = error_message(ENOMEM); 73 return ENOMEM; 74 } 75 76 /* This song-and-dance effectivly puts the principal 77 * into talloc, so we can't loose it. */ 78 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); 79 mem_ctx->principal = *princ; 80 talloc_set_destructor(mem_ctx, free_principal); 81 return 0; 82 } 83 84 static krb5_error_code principals_from_msg(TALLOC_CTX *parent_ctx, 85 struct ldb_message *msg, 86 struct smb_krb5_context *smb_krb5_context, 87 struct principal_container ***principals_out, 88 const char **error_string) 89 { 90 unsigned int i; 48 91 krb5_error_code ret; 49 char *machine_username; 50 char *salt_body; 51 char *lower_realm; 52 const char *salt_principal; 53 struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container); 54 if (!mem_ctx) { 55 return ENOMEM; 56 } 57 58 salt_principal = cli_credentials_get_salt_principal(machine_account); 92 char *upper_realm; 93 const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL); 94 const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); 95 struct ldb_message_element *spn_el = ldb_msg_find_element(msg, "servicePrincipalName"); 96 TALLOC_CTX *tmp_ctx; 97 struct principal_container **principals; 98 tmp_ctx = talloc_new(parent_ctx); 99 if (!tmp_ctx) { 100 *error_string = "Cannot allocate tmp_ctx"; 101 return ENOMEM; 102 } 103 104 if (!realm) { 105 *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm"; 106 return EINVAL; 107 } 108 109 upper_realm = strupper_talloc(tmp_ctx, realm); 110 if (!upper_realm) { 111 talloc_free(tmp_ctx); 112 *error_string = "Cannot allocate full upper case realm"; 113 return ENOMEM; 114 } 115 116 principals = talloc_array(tmp_ctx, struct principal_container *, spn_el ? (spn_el->num_values + 2) : 2); 117 118 spn_el = ldb_msg_find_element(msg, "servicePrincipalName"); 119 for (i=0; spn_el && i < spn_el->num_values; i++) { 120 principals[i] = talloc(principals, struct principal_container); 121 if (!principals[i]) { 122 talloc_free(tmp_ctx); 123 *error_string = "Cannot allocate mem_ctx"; 124 return ENOMEM; 125 } 126 127 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context); 128 principals[i]->string_form = talloc_asprintf(principals[i], "%*.*s@%s", 129 (int)spn_el->values[i].length, 130 (int)spn_el->values[i].length, 131 (const char *)spn_el->values[i].data, upper_realm); 132 if (!principals[i]->string_form) { 133 talloc_free(tmp_ctx); 134 *error_string = "Cannot allocate full samAccountName"; 135 return ENOMEM; 136 } 137 138 ret = krb5_parse_name(smb_krb5_context->krb5_context, 139 principals[i]->string_form, &principals[i]->principal); 140 141 if (ret) { 142 talloc_free(tmp_ctx); 143 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); 144 return ret; 145 } 146 147 /* This song-and-dance effectivly puts the principal 148 * into talloc, so we can't loose it. */ 149 talloc_set_destructor(principals[i], free_principal); 150 } 151 152 if (samAccountName) { 153 principals[i] = talloc(principals, struct principal_container); 154 if (!principals[i]) { 155 talloc_free(tmp_ctx); 156 *error_string = "Cannot allocate mem_ctx"; 157 return ENOMEM; 158 } 159 160 principals[i]->smb_krb5_context = talloc_reference(principals[i], smb_krb5_context); 161 principals[i]->string_form = talloc_asprintf(parent_ctx, "%s@%s", samAccountName, upper_realm); 162 if (!principals[i]->string_form) { 163 talloc_free(tmp_ctx); 164 *error_string = "Cannot allocate full samAccountName"; 165 return ENOMEM; 166 } 167 168 ret = krb5_make_principal(smb_krb5_context->krb5_context, &principals[i]->principal, upper_realm, samAccountName, 169 NULL); 170 if (ret) { 171 talloc_free(tmp_ctx); 172 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); 173 return ret; 174 } 175 176 /* This song-and-dance effectivly puts the principal 177 * into talloc, so we can't loose it. */ 178 talloc_set_destructor(principals[i], free_principal); 179 i++; 180 } 181 182 principals[i] = NULL; 183 *principals_out = talloc_steal(parent_ctx, principals); 184 185 talloc_free(tmp_ctx); 186 return ret; 187 } 188 189 static krb5_error_code salt_principal_from_msg(TALLOC_CTX *parent_ctx, 190 struct ldb_message *msg, 191 struct smb_krb5_context *smb_krb5_context, 192 krb5_principal *salt_princ, 193 const char **error_string) 194 { 195 const char *salt_principal = ldb_msg_find_attr_as_string(msg, "saltPrincipal", NULL); 196 const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL); 197 const char *realm = ldb_msg_find_attr_as_string(msg, "realm", NULL); 59 198 if (salt_principal) { 60 ret = krb5_parse_name(smb_krb5_context->krb5_context, salt_principal, salt_princ); 61 } else { 62 machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account)); 63 199 return parse_principal(parent_ctx, salt_principal, smb_krb5_context, salt_princ, error_string); 200 } else if (samAccountName) { 201 krb5_error_code ret; 202 char *machine_username; 203 char *salt_body; 204 char *lower_realm; 205 char *upper_realm; 206 207 TALLOC_CTX *tmp_ctx; 208 struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container); 209 if (!mem_ctx) { 210 *error_string = "Cannot allocate mem_ctx"; 211 return ENOMEM; 212 } 213 214 tmp_ctx = talloc_new(mem_ctx); 215 if (!tmp_ctx) { 216 talloc_free(mem_ctx); 217 *error_string = "Cannot allocate tmp_ctx"; 218 return ENOMEM; 219 } 220 221 if (!realm) { 222 *error_string = "Cannot have a kerberos secret in secrets.ldb without a realm"; 223 return EINVAL; 224 } 225 226 machine_username = talloc_strdup(tmp_ctx, samAccountName); 64 227 if (!machine_username) { 65 228 talloc_free(mem_ctx); 229 *error_string = "Cannot duplicate samAccountName"; 66 230 return ENOMEM; 67 231 } … … 70 234 machine_username[strlen(machine_username)-1] = '\0'; 71 235 } 72 lower_realm = strlower_talloc(mem_ctx, cli_credentials_get_realm(machine_account)); 236 237 lower_realm = strlower_talloc(tmp_ctx, realm); 73 238 if (!lower_realm) { 74 239 talloc_free(mem_ctx); 240 *error_string = "Cannot allocate to lower case realm"; 75 241 return ENOMEM; 76 242 } 77 243 78 salt_body = talloc_asprintf(mem_ctx, "%s.%s", machine_username, 244 upper_realm = strupper_talloc(tmp_ctx, realm); 245 if (!upper_realm) { 246 talloc_free(mem_ctx); 247 *error_string = "Cannot allocate to upper case realm"; 248 return ENOMEM; 249 } 250 251 salt_body = talloc_asprintf(tmp_ctx, "%s.%s", machine_username, 79 252 lower_realm); 253 talloc_free(lower_realm); 254 talloc_free(machine_username); 80 255 if (!salt_body) { 81 256 talloc_free(mem_ctx); 82 return ENOMEM; 257 *error_string = "Cannot form salt principal body"; 258 return ENOMEM; 83 259 } 84 260 85 261 ret = krb5_make_principal(smb_krb5_context->krb5_context, salt_princ, 86 cli_credentials_get_realm(machine_account),262 upper_realm, 87 263 "host", salt_body, NULL); 88 } 89 90 if (ret == 0) { 91 /* This song-and-dance effectivly puts the principal 92 * into talloc, so we can't loose it. */ 93 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); 94 mem_ctx->principal = *salt_princ; 95 talloc_set_destructor(mem_ctx, free_principal); 96 } 97 return ret; 264 if (ret == 0) { 265 /* This song-and-dance effectivly puts the principal 266 * into talloc, so we can't loose it. */ 267 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); 268 mem_ctx->principal = *salt_princ; 269 talloc_set_destructor(mem_ctx, free_principal); 270 } else { 271 (*error_string) = smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, parent_ctx); 272 } 273 talloc_free(tmp_ctx); 274 return ret; 275 } else { 276 (*error_string) = "Cannot determine salt principal, no saltPrincipal or samAccountName specified"; 277 return EINVAL; 278 } 98 279 } 99 280 … … 103 284 * system by means of a destructor (do *not* free). */ 104 285 105 286 krb5_error_code principal_from_credentials(TALLOC_CTX *parent_ctx, 106 287 struct cli_credentials *credentials, 107 288 struct smb_krb5_context *smb_krb5_context, 108 krb5_principal *princ) 289 krb5_principal *princ, 290 enum credentials_obtained *obtained, 291 const char **error_string) 109 292 { 110 293 krb5_error_code ret; 111 294 const char *princ_string; 112 struct principal_container *mem_ctx = talloc(parent_ctx, struct principal_container);295 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 113 296 if (!mem_ctx) { 114 return ENOMEM; 115 } 116 117 princ_string = cli_credentials_get_principal(credentials, mem_ctx); 118 119 /* A NULL here has meaning, as the gssapi server case will 120 * then use the principal from the client */ 297 (*error_string) = error_message(ENOMEM); 298 return ENOMEM; 299 } 300 princ_string = cli_credentials_get_principal_and_obtained(credentials, mem_ctx, obtained); 121 301 if (!princ_string) { 122 talloc_free(mem_ctx); 123 princ = NULL; 124 return 0; 125 } 126 127 ret = krb5_parse_name(smb_krb5_context->krb5_context, 128 princ_string, princ); 129 130 if (ret == 0) { 131 /* This song-and-dance effectivly puts the principal 132 * into talloc, so we can't loose it. */ 133 mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context); 134 mem_ctx->principal = *princ; 135 talloc_set_destructor(mem_ctx, free_principal); 136 } 302 (*error_string) = error_message(ENOMEM); 303 return ENOMEM; 304 } 305 306 ret = parse_principal(parent_ctx, princ_string, 307 smb_krb5_context, princ, error_string); 308 talloc_free(mem_ctx); 137 309 return ret; 310 } 311 312 /* Obtain the principal set on this context. Requires a 313 * smb_krb5_context because we are doing krb5 principal parsing with 314 * the library routines. The returned princ is placed in the talloc 315 * system by means of a destructor (do *not* free). */ 316 317 krb5_error_code impersonate_principal_from_credentials(TALLOC_CTX *parent_ctx, 318 struct cli_credentials *credentials, 319 struct smb_krb5_context *smb_krb5_context, 320 krb5_principal *princ, 321 const char **error_string) 322 { 323 return parse_principal(parent_ctx, cli_credentials_get_impersonate_principal(credentials), 324 smb_krb5_context, princ, error_string); 138 325 } 139 326 … … 146 333 struct cli_credentials *credentials, 147 334 struct smb_krb5_context *smb_krb5_context, 148 krb5_ccache ccache) 335 struct tevent_context *event_ctx, 336 krb5_ccache ccache, 337 enum credentials_obtained *obtained, 338 const char **error_string) 149 339 { 150 340 krb5_error_code ret; 151 const char *password ;341 const char *password, *target_service; 152 342 time_t kdc_time = 0; 153 343 krb5_principal princ; 344 krb5_principal impersonate_principal; 154 345 int tries; 155 346 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 347 krb5_get_init_creds_opt *krb_options; 156 348 157 349 if (!mem_ctx) { 158 return ENOMEM; 159 } 160 161 ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ); 350 (*error_string) = strerror(ENOMEM); 351 return ENOMEM; 352 } 353 354 ret = principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &princ, obtained, error_string); 162 355 if (ret) { 163 356 talloc_free(mem_ctx); … … 165 358 } 166 359 360 ret = impersonate_principal_from_credentials(mem_ctx, credentials, smb_krb5_context, &impersonate_principal, error_string); 361 if (ret) { 362 talloc_free(mem_ctx); 363 return ret; 364 } 365 366 target_service = cli_credentials_get_target_service(credentials); 367 167 368 password = cli_credentials_get_password(credentials); 369 370 /* setup the krb5 options we want */ 371 if ((ret = krb5_get_init_creds_opt_alloc(smb_krb5_context->krb5_context, &krb_options))) { 372 (*error_string) = talloc_asprintf(credentials, "krb5_get_init_creds_opt_alloc failed (%s)\n", 373 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 374 ret, mem_ctx)); 375 talloc_free(mem_ctx); 376 return ret; 377 } 378 379 /* get the defaults */ 380 krb5_get_init_creds_opt_set_default_flags(smb_krb5_context->krb5_context, NULL, NULL, krb_options); 381 382 /* set if we want a forwardable ticket */ 383 switch (cli_credentials_get_krb_forwardable(credentials)) { 384 case CRED_AUTO_KRB_FORWARDABLE: 385 break; 386 case CRED_NO_KRB_FORWARDABLE: 387 krb5_get_init_creds_opt_set_forwardable(krb_options, FALSE); 388 break; 389 case CRED_FORCE_KRB_FORWARDABLE: 390 krb5_get_init_creds_opt_set_forwardable(krb_options, TRUE); 391 break; 392 } 168 393 169 394 tries = 2; 170 395 while (tries--) { 396 struct tevent_context *previous_ev; 397 /* Do this every time, in case we have weird recursive issues here */ 398 ret = smb_krb5_context_set_event_ctx(smb_krb5_context, event_ctx, &previous_ev); 399 if (ret) { 400 talloc_free(mem_ctx); 401 return ret; 402 } 171 403 if (password) { 172 404 ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache, 173 princ, 174 password, NULL, &kdc_time); 405 princ, password, 406 impersonate_principal, target_service, 407 krb_options, 408 NULL, &kdc_time); 409 } else if (impersonate_principal) { 410 talloc_free(mem_ctx); 411 (*error_string) = "INTERNAL error: Cannot impersonate principal with just a keyblock. A password must be specified in the credentials"; 412 return EINVAL; 175 413 } else { 176 414 /* No password available, try to use a keyblock instead */ … … 181 419 if (!mach_pwd) { 182 420 talloc_free(mem_ctx); 183 DEBUG(1, ("kinit_to_ccache: No password available for kinit\n")); 421 (*error_string) = "kinit_to_ccache: No password available for kinit\n"; 422 krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options); 423 smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx); 184 424 return EINVAL; 185 425 } … … 191 431 if (ret == 0) { 192 432 ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, ccache, 193 princ, 194 &keyblock, NULL, &kdc_time); 433 princ, &keyblock, 434 target_service, krb_options, 435 NULL, &kdc_time); 195 436 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &keyblock); 196 437 } 197 438 } 439 440 smb_krb5_context_remove_event_ctx(smb_krb5_context, previous_ev, event_ctx); 198 441 199 442 if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { … … 207 450 } 208 451 452 krb5_get_init_creds_opt_free(smb_krb5_context->krb5_context, krb_options); 453 209 454 if (ret == KRB5KRB_AP_ERR_SKEW || ret == KRB5_KDCREP_SKEW) { 210 DEBUG(1,("kinit for %s failed (%s)\n",211 cli_credentials_get_principal(credentials, mem_ctx),212 smb_get_krb5_error_message(smb_krb5_context->krb5_context,213 ret, mem_ctx)));455 (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n", 456 cli_credentials_get_principal(credentials, mem_ctx), 457 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 458 ret, mem_ctx)); 214 459 talloc_free(mem_ctx); 215 460 return ret; … … 228 473 credentials, 229 474 smb_krb5_context, 230 ccache); 231 } 475 event_ctx, 476 ccache, obtained, 477 error_string); 478 } 479 232 480 if (ret) { 233 DEBUG(1,("kinit for %s failed (%s)\n",234 cli_credentials_get_principal(credentials, mem_ctx),235 smb_get_krb5_error_message(smb_krb5_context->krb5_context,236 ret, mem_ctx)));481 (*error_string) = talloc_asprintf(credentials, "kinit for %s failed (%s)\n", 482 cli_credentials_get_principal(credentials, mem_ctx), 483 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 484 ret, mem_ctx)); 237 485 talloc_free(mem_ctx); 238 486 return ret; … … 274 522 275 523 static krb5_error_code keytab_add_keys(TALLOC_CTX *parent_ctx, 276 const char *princ_string, 277 krb5_principal princ, 524 struct principal_container **principals, 278 525 krb5_principal salt_princ, 279 526 int kvno, 280 527 const char *password_s, 281 528 struct smb_krb5_context *smb_krb5_context, 282 const char **enctype_strings, 283 krb5_keytab keytab) 284 { 285 int i; 529 krb5_enctype *enctypes, 530 krb5_keytab keytab, 531 const char **error_string) 532 { 533 unsigned int i, p; 286 534 krb5_error_code ret; 287 535 krb5_data password; 288 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);289 if (!mem_ctx) {290 return ENOMEM;291 }292 536 293 537 password.data = discard_const_p(char *, password_s); 294 538 password.length = strlen(password_s); 295 539 296 for (i=0; enctype _strings[i]; i++) {540 for (i=0; enctypes[i]; i++) { 297 541 krb5_keytab_entry entry; 298 krb5_enctype enctype; 299 ret = krb5_string_to_enctype(smb_krb5_context->krb5_context, enctype_strings[i], &enctype); 542 543 ZERO_STRUCT(entry); 544 545 ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context, 546 salt_princ, &password, &entry.keyblock, enctypes[i]); 300 547 if (ret != 0) { 301 DEBUG(1, ("Failed to interpret %s as a krb5 encryption type: %s\n",302 enctype_strings[i],303 smb_get_krb5_error_message(smb_krb5_context->krb5_context,304 ret, mem_ctx)));305 talloc_free(mem_ctx);306 548 return ret; 307 549 } 308 ret = create_kerberos_key_from_string(smb_krb5_context->krb5_context, 309 salt_princ, &password, &entry.keyblock, enctype); 310 if (ret != 0) { 311 talloc_free(mem_ctx); 312 return ret; 313 } 314 315 entry.principal = princ; 316 entry.vno = kvno; 317 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry); 318 if (ret != 0) { 319 DEBUG(1, ("Failed to add %s entry for %s(kvno %d) to keytab: %s\n", 320 enctype_strings[i], 321 princ_string, 322 kvno, 323 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 324 ret, mem_ctx))); 325 talloc_free(mem_ctx); 326 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); 327 return ret; 328 } 329 330 DEBUG(5, ("Added %s(kvno %d) to keytab (%s)\n", 331 princ_string, kvno, 332 enctype_strings[i])); 333 550 551 entry.vno = kvno; 552 553 for (p=0; principals[p]; p++) { 554 entry.principal = principals[p]->principal; 555 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry); 556 if (ret != 0) { 557 char *k5_error_string = smb_get_krb5_error_message(smb_krb5_context->krb5_context, 558 ret, NULL); 559 *error_string = talloc_asprintf(parent_ctx, "Failed to add enctype %d entry for %s(kvno %d) to keytab: %s\n", 560 (int)enctypes[i], 561 principals[p]->string_form, 562 kvno, 563 k5_error_string); 564 talloc_free(k5_error_string); 565 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); 566 return ret; 567 } 568 569 DEBUG(5, ("Added %s(kvno %d) to keytab (enctype %d)\n", 570 principals[p]->string_form, kvno, 571 (int)enctypes[i])); 572 } 334 573 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock); 335 574 } 336 talloc_free(mem_ctx);337 575 return 0; 338 576 } 339 577 340 578 static krb5_error_code create_keytab(TALLOC_CTX *parent_ctx, 341 struct cli_credentials *machine_account, 342 struct smb_krb5_context *smb_krb5_context, 343 const char **enctype_strings, 344 krb5_keytab keytab, 345 bool add_old) 579 struct ldb_message *msg, 580 struct principal_container **principals, 581 struct smb_krb5_context *smb_krb5_context, 582 krb5_keytab keytab, 583 bool add_old, 584 const char **error_string) 346 585 { 347 586 krb5_error_code ret; … … 349 588 const char *old_secret; 350 589 int kvno; 590 uint32_t enctype_bitmap; 351 591 krb5_principal salt_princ; 352 krb5_principal princ; 353 const char *princ_string; 354 592 krb5_enctype *enctypes; 355 593 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 356 594 if (!mem_ctx) { 357 return ENOMEM; 358 } 359 360 princ_string = cli_credentials_get_principal(machine_account, mem_ctx); 361 /* Get the principal we will store the new keytab entries under */ 362 ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ); 595 *error_string = "unable to allocate tmp_ctx for create_keytab"; 596 return ENOMEM; 597 } 598 599 /* The salt used to generate these entries may be different however, fetch that */ 600 ret = salt_principal_from_msg(mem_ctx, msg, 601 smb_krb5_context, 602 &salt_princ, error_string); 363 603 if (ret) { 364 DEBUG(1,("create_keytab: makeing krb5 principal failed (%s)\n", 365 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 366 ret, mem_ctx))); 367 talloc_free(mem_ctx); 368 return ret; 369 } 370 371 /* The salt used to generate these entries may be different however, fetch that */ 372 ret = salt_principal_from_credentials(mem_ctx, machine_account, 373 smb_krb5_context, 374 &salt_princ); 604 talloc_free(mem_ctx); 605 return ret; 606 } 607 608 kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0); 609 610 /* Finally, do the dance to get the password to put in the entry */ 611 password_s = ldb_msg_find_attr_as_string(msg, "secret", NULL); 612 613 if (!password_s) { 614 /* There is no password here, so nothing to do */ 615 talloc_free(mem_ctx); 616 return 0; 617 } 618 619 if (add_old && kvno != 0) { 620 old_secret = ldb_msg_find_attr_as_string(msg, "priorSecret", NULL); 621 } else { 622 old_secret = NULL; 623 } 624 625 enctype_bitmap = (uint32_t)ldb_msg_find_attr_as_int(msg, "msDS-SupportedEncryptionTypes", ENC_ALL_TYPES); 626 627 ret = kerberos_enctype_bitmap_to_enctypes(mem_ctx, enctype_bitmap, &enctypes); 375 628 if (ret) { 376 DEBUG(1,("create_keytab: makeing salt principal failed (%s)\n", 377 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 378 ret, mem_ctx))); 379 talloc_free(mem_ctx); 380 return ret; 381 } 382 383 /* Finally, do the dance to get the password to put in the entry */ 384 password_s = cli_credentials_get_password(machine_account); 385 if (!password_s) { 386 krb5_keytab_entry entry; 387 const struct samr_Password *mach_pwd; 388 389 if (!str_list_check(enctype_strings, "arcfour-hmac-md5")) { 390 DEBUG(1, ("Asked to create keytab, but with only an NT hash supplied, " 391 "but not listing arcfour-hmac-md5 as an enc type to include in the keytab!\n")); 392 talloc_free(mem_ctx); 393 return EINVAL; 394 } 395 396 /* If we don't have the plaintext password, try for 397 * the MD4 password hash */ 398 mach_pwd = cli_credentials_get_nt_hash(machine_account, mem_ctx); 399 if (!mach_pwd) { 400 /* OK, nothing to do here */ 401 talloc_free(mem_ctx); 402 return 0; 403 } 404 ret = krb5_keyblock_init(smb_krb5_context->krb5_context, 405 ETYPE_ARCFOUR_HMAC_MD5, 406 mach_pwd->hash, sizeof(mach_pwd->hash), 407 &entry.keyblock); 629 *error_string = talloc_asprintf(parent_ctx, "create_keytab: generating list of encryption types failed (%s)\n", 630 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 631 ret, mem_ctx)); 632 talloc_free(mem_ctx); 633 return ret; 634 } 635 636 ret = keytab_add_keys(mem_ctx, principals, 637 salt_princ, 638 kvno, password_s, smb_krb5_context, 639 enctypes, keytab, error_string); 640 if (ret) { 641 talloc_free(mem_ctx); 642 return ret; 643 } 644 645 if (old_secret) { 646 ret = keytab_add_keys(mem_ctx, principals, 647 salt_princ, 648 kvno - 1, old_secret, smb_krb5_context, 649 enctypes, keytab, error_string); 408 650 if (ret) { 409 DEBUG(1, ("create_keytab: krb5_keyblock_init failed: %s\n",410 smb_get_krb5_error_message(smb_krb5_context->krb5_context,411 ret, mem_ctx)));412 651 talloc_free(mem_ctx); 413 652 return ret; 414 653 } 415 416 entry.principal = princ;417 entry.vno = cli_credentials_get_kvno(machine_account);418 ret = krb5_kt_add_entry(smb_krb5_context->krb5_context, keytab, &entry);419 if (ret) {420 DEBUG(1, ("Failed to add ARCFOUR_HMAC (only) entry for %s to keytab: %s",421 cli_credentials_get_principal(machine_account, mem_ctx),422 smb_get_krb5_error_message(smb_krb5_context->krb5_context,423 ret, mem_ctx)));424 talloc_free(mem_ctx);425 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);426 return ret;427 }428 429 DEBUG(5, ("Added %s(kvno %d) to keytab (arcfour-hmac-md5)\n",430 cli_credentials_get_principal(machine_account, mem_ctx),431 cli_credentials_get_kvno(machine_account)));432 433 krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &entry.keyblock);434 435 /* Can't go any further, we only have this one key */436 talloc_free(mem_ctx);437 return 0;438 }439 440 kvno = cli_credentials_get_kvno(machine_account);441 /* good, we actually have the real plaintext */442 ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ,443 kvno, password_s, smb_krb5_context,444 enctype_strings, keytab);445 if (!ret) {446 talloc_free(mem_ctx);447 return ret;448 }449 450 if (!add_old || kvno == 0) {451 talloc_free(mem_ctx);452 return 0;453 }454 455 old_secret = cli_credentials_get_old_password(machine_account);456 if (!old_secret) {457 talloc_free(mem_ctx);458 return 0;459 }460 461 ret = keytab_add_keys(mem_ctx, princ_string, princ, salt_princ,462 kvno - 1, old_secret, smb_krb5_context,463 enctype_strings, keytab);464 if (!ret) {465 talloc_free(mem_ctx);466 return ret;467 654 } 468 655 469 656 talloc_free(mem_ctx); 470 return 0; 471 } 472 657 return ret; 658 } 473 659 474 660 /* … … 482 668 483 669 static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx, 484 struct cli_credentials *machine_account, 670 struct ldb_message *msg, 671 struct principal_container **principals, 672 bool delete_all_kvno, 485 673 struct smb_krb5_context *smb_krb5_context, 486 krb5_keytab keytab, bool *found_previous) 674 krb5_keytab keytab, bool *found_previous, 675 const char **error_string) 487 676 { 488 677 krb5_error_code ret, ret2; 489 678 krb5_kt_cursor cursor; 490 krb5_principal princ;491 679 int kvno; 492 680 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 493 const char *princ_string; 681 494 682 if (!mem_ctx) { 495 683 return ENOMEM; … … 497 685 498 686 *found_previous = false; 499 princ_string = cli_credentials_get_principal(machine_account, mem_ctx); 500 501 /* Get the principal we will store the new keytab entries under */ 502 ret = principal_from_credentials(mem_ctx, machine_account, smb_krb5_context, &princ); 503 if (ret) { 504 DEBUG(1,("update_keytab: makeing krb5 principal failed (%s)\n", 505 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 506 ret, mem_ctx))); 507 talloc_free(mem_ctx); 508 return ret; 509 } 510 511 kvno = cli_credentials_get_kvno(machine_account); 687 688 kvno = ldb_msg_find_attr_as_int(msg, "msDS-KeyVersionNumber", 0); 512 689 513 690 /* for each entry in the keytab */ … … 523 700 return 0; 524 701 default: 525 DEBUG(1,("failed to open keytab for read of old entries: %s\n",526 smb_get_krb5_error_message(smb_krb5_context->krb5_context,527 ret, mem_ctx)));702 *error_string = talloc_asprintf(parent_ctx, "failed to open keytab for read of old entries: %s\n", 703 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 704 ret, mem_ctx)); 528 705 talloc_free(mem_ctx); 529 706 return ret; … … 531 708 532 709 while (!ret) { 710 unsigned int i; 711 bool matched = false; 533 712 krb5_keytab_entry entry; 534 713 ret = krb5_kt_next_entry(smb_krb5_context->krb5_context, keytab, &entry, &cursor); … … 536 715 break; 537 716 } 538 /* if it matches our principal */ 539 if (!krb5_kt_compare(smb_krb5_context->krb5_context, &entry, princ, 0, 0)) { 717 for (i = 0; principals[i]; i++) { 718 /* if it matches our principal */ 719 if (krb5_kt_compare(smb_krb5_context->krb5_context, &entry, principals[i]->principal, 0, 0)) { 720 matched = true; 721 break; 722 } 723 } 724 725 if (!matched) { 540 726 /* Free the entry, it wasn't the one we were looking for anyway */ 541 727 krb5_kt_free_entry(smb_krb5_context->krb5_context, &entry); … … 593 779 break; 594 780 default: 595 DEBUG(1,("failed in deleting old entries for principal: %s: %s\n", 596 princ_string, 597 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 598 ret, mem_ctx))); 781 *error_string = talloc_asprintf(parent_ctx, "failed in deleting old entries for principal: %s\n", 782 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 783 ret, mem_ctx)); 599 784 } 600 785 talloc_free(mem_ctx); … … 603 788 604 789 krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx, 605 struct cli_credentials *machine_account, 606 struct smb_krb5_context *smb_krb5_context, 607 const char **enctype_strings, 608 struct keytab_container *keytab_container) 790 struct smb_krb5_context *smb_krb5_context, 791 struct ldb_context *ldb, 792 struct ldb_message *msg, 793 bool delete_all_kvno, 794 const char **error_string) 609 795 { 610 796 krb5_error_code ret; 611 797 bool found_previous; 612 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 798 TALLOC_CTX *mem_ctx = talloc_new(NULL); 799 struct keytab_container *keytab_container; 800 struct principal_container **principals; 801 const char *keytab_name; 802 613 803 if (!mem_ctx) { 614 804 return ENOMEM; 615 805 } 616 806 617 ret = remove_old_entries(mem_ctx, machine_account, 618 smb_krb5_context, keytab_container->keytab, &found_previous); 807 keytab_name = keytab_name_from_msg(mem_ctx, ldb, msg); 808 if (!keytab_name) { 809 return ENOENT; 810 } 811 812 ret = smb_krb5_open_keytab(mem_ctx, smb_krb5_context, keytab_name, &keytab_container); 813 619 814 if (ret != 0) { 620 815 talloc_free(mem_ctx); 621 816 return ret; 622 817 } 818 819 DEBUG(5, ("Opened keytab %s\n", keytab_name)); 820 821 /* Get the principal we will store the new keytab entries under */ 822 ret = principals_from_msg(mem_ctx, msg, smb_krb5_context, &principals, error_string); 823 824 if (ret != 0) { 825 *error_string = talloc_asprintf(parent_ctx, "Failed to load principals from ldb message: %s\n", *error_string); 826 talloc_free(mem_ctx); 827 return ret; 828 } 829 830 ret = remove_old_entries(mem_ctx, msg, principals, delete_all_kvno, 831 smb_krb5_context, keytab_container->keytab, &found_previous, error_string); 832 if (ret != 0) { 833 *error_string = talloc_asprintf(parent_ctx, "Failed to remove old principals from keytab: %s\n", *error_string); 834 talloc_free(mem_ctx); 835 return ret; 836 } 623 837 624 /* Create a new keytab. If during the cleanout we found 625 * entires for kvno -1, then don't try and duplicate them. 626 * Otherwise, add kvno, and kvno -1 */ 627 628 ret = create_keytab(mem_ctx, machine_account, smb_krb5_context, 629 enctype_strings, 630 keytab_container->keytab, 631 found_previous ? false : true); 838 if (!delete_all_kvno) { 839 /* Create a new keytab. If during the cleanout we found 840 * entires for kvno -1, then don't try and duplicate them. 841 * Otherwise, add kvno, and kvno -1 */ 842 843 ret = create_keytab(mem_ctx, msg, principals, 844 smb_krb5_context, 845 keytab_container->keytab, 846 found_previous ? false : true, error_string); 847 } 632 848 talloc_free(mem_ctx); 633 849 return ret; … … 637 853 struct cli_credentials *machine_account, 638 854 struct smb_krb5_context *smb_krb5_context, 639 const char **enctype_strings,640 855 struct keytab_container **keytab_container) 641 856 { … … 644 859 const char *rand_string; 645 860 const char *keytab_name; 861 struct ldb_message *msg; 862 const char *error_string; 646 863 if (!mem_ctx) { 647 864 return ENOMEM; … … 668 885 } 669 886 670 ret = smb_krb5_update_keytab(mem_ctx, machine_account, smb_krb5_context, enctype_strings, *keytab_container); 887 msg = ldb_msg_new(mem_ctx); 888 if (!msg) { 889 talloc_free(mem_ctx); 890 return ENOMEM; 891 } 892 ldb_msg_add_string(msg, "krb5Keytab", keytab_name); 893 ldb_msg_add_string(msg, "secret", cli_credentials_get_password(machine_account)); 894 ldb_msg_add_string(msg, "samAccountName", cli_credentials_get_username(machine_account)); 895 ldb_msg_add_string(msg, "realm", cli_credentials_get_realm(machine_account)); 896 ldb_msg_add_fmt(msg, "msDS-KeyVersionNumber", "%d", (int)cli_credentials_get_kvno(machine_account)); 897 898 ret = smb_krb5_update_keytab(mem_ctx, smb_krb5_context, NULL, msg, false, &error_string); 671 899 if (ret == 0) { 672 900 talloc_steal(parent_ctx, *keytab_container); 673 901 } else { 902 DEBUG(0, ("Failed to create in-memory keytab: %s\n", error_string)); 674 903 *keytab_container = NULL; 675 904 } … … 677 906 return ret; 678 907 } 679 908 /* Translate between the IETF encryption type values and the Microsoft msDS-SupportedEncryptionTypes values */ 909 uint32_t kerberos_enctype_to_bitmap(krb5_enctype enc_type_enum) 910 { 911 switch (enc_type_enum) { 912 case ENCTYPE_DES_CBC_CRC: 913 return ENC_CRC32; 914 case ENCTYPE_DES_CBC_MD5: 915 return ENC_RSA_MD5; 916 case ENCTYPE_ARCFOUR_HMAC_MD5: 917 return ENC_RC4_HMAC_MD5; 918 case ENCTYPE_AES128_CTS_HMAC_SHA1_96: 919 return ENC_HMAC_SHA1_96_AES128; 920 case ENCTYPE_AES256_CTS_HMAC_SHA1_96: 921 return ENC_HMAC_SHA1_96_AES256; 922 default: 923 return 0; 924 } 925 } 926 927 /* Translate between the Microsoft msDS-SupportedEncryptionTypes values and the IETF encryption type values */ 928 krb5_enctype kerberos_enctype_bitmap_to_enctype(uint32_t enctype_bitmap) 929 { 930 switch (enctype_bitmap) { 931 case ENC_CRC32: 932 return ENCTYPE_DES_CBC_CRC; 933 case ENC_RSA_MD5: 934 return ENCTYPE_DES_CBC_MD5; 935 case ENC_RC4_HMAC_MD5: 936 return ENCTYPE_ARCFOUR_HMAC_MD5; 937 case ENC_HMAC_SHA1_96_AES128: 938 return ENCTYPE_AES128_CTS_HMAC_SHA1_96; 939 case ENC_HMAC_SHA1_96_AES256: 940 return ENCTYPE_AES256_CTS_HMAC_SHA1_96; 941 default: 942 return 0; 943 } 944 } 945 946 /* Return an array of krb5_enctype values */ 947 krb5_error_code kerberos_enctype_bitmap_to_enctypes(TALLOC_CTX *mem_ctx, uint32_t enctype_bitmap, krb5_enctype **enctypes) 948 { 949 unsigned int i, j = 0; 950 *enctypes = talloc_zero_array(mem_ctx, krb5_enctype, (8*sizeof(enctype_bitmap))+1); 951 if (!*enctypes) { 952 return ENOMEM; 953 } 954 for (i=0; i<(8*sizeof(enctype_bitmap)); i++) { 955 uint32_t bit_value = (1 << i) & enctype_bitmap; 956 if (bit_value & enctype_bitmap) { 957 (*enctypes)[j] = kerberos_enctype_bitmap_to_enctype(bit_value); 958 if (!(*enctypes)[j]) { 959 continue; 960 } 961 j++; 962 } 963 } 964 (*enctypes)[j] = 0; 965 return 0; 966 } -
vendor/current/source4/auth/kerberos/krb5_init_context.c
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Wrapper for krb5_init_context … … 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 30 30 #include "param/param.h" 31 31 #include "libcli/resolve/resolve.h" 32 #include "../lib/tsocket/tsocket.h" 32 33 33 34 /* … … 42 43 NTSTATUS status; 43 44 DATA_BLOB request, reply; 44 45 45 46 struct packet_context *packet; 46 47 … … 50 51 }; 51 52 52 static krb5_error_code smb_krb5_context_destroy_1(struct smb_krb5_context *ctx) 53 { 54 krb5_free_context(ctx->krb5_context); 55 return 0; 56 } 57 58 static krb5_error_code smb_krb5_context_destroy_2(struct smb_krb5_context *ctx) 53 static krb5_error_code smb_krb5_context_destroy(struct smb_krb5_context *ctx) 59 54 { 60 55 /* Otherwise krb5_free_context will try and close what we have already free()ed */ 61 56 krb5_set_warn_dest(ctx->krb5_context, NULL); 62 57 krb5_closelog(ctx->krb5_context, ctx->logf); 63 smb_krb5_context_destroy_1(ctx);58 krb5_free_context(ctx->krb5_context); 64 59 return 0; 65 60 } … … 72 67 static void smb_krb5_debug_wrapper(const char *timestr, const char *msg, void *private_data) 73 68 { 74 DEBUG( 2, ("Kerberos: %s\n", msg));69 DEBUG(3, ("Kerberos: %s\n", msg)); 75 70 } 76 71 … … 89 84 return; 90 85 } 91 86 92 87 blob = data_blob_talloc(tmp_ctx, NULL, dsize); 93 88 if (blob.data == NULL && dsize != 0) { … … 96 91 return; 97 92 } 98 93 99 94 smb_krb5->status = socket_recv(smb_krb5->sock, blob.data, blob.length, &nread); 100 95 if (!NT_STATUS_IS_OK(smb_krb5->status)) { … … 103 98 } 104 99 blob.length = nread; 105 100 106 101 if (nread == 0) { 107 102 smb_krb5->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; … … 109 104 return; 110 105 } 111 112 DEBUG(2,("Received smb_krb5 packet of length %d\n", 106 107 DEBUG(2,("Received smb_krb5 packet of length %d\n", 113 108 (int)blob.length)); 114 109 115 110 talloc_steal(smb_krb5, blob.data); 116 111 smb_krb5->reply = blob; … … 131 126 handle request timeouts 132 127 */ 133 static void smb_krb5_request_timeout(struct tevent_context *event_ctx, 128 static void smb_krb5_request_timeout(struct tevent_context *event_ctx, 134 129 struct tevent_timer *te, struct timeval t, 135 130 void *private_data) … … 154 149 155 150 size_t len; 156 151 157 152 len = smb_krb5->request.length; 158 153 status = socket_send(smb_krb5->sock, &smb_krb5->request, &len); 159 154 160 155 if (!NT_STATUS_IS_OK(status)) return; 161 156 162 157 TEVENT_FD_READABLE(smb_krb5->fde); 163 158 … … 213 208 krb5_error_code ret; 214 209 NTSTATUS status; 215 struct socket_address *remote_addr;216 210 const char *name; 217 211 struct addrinfo *ai, *a; 218 212 struct smb_krb5_socket *smb_krb5; 219 213 220 struct tevent_context *ev = talloc_get_type(data, struct tevent_context); 221 222 DATA_BLOB send_blob = data_blob_const(send_buf->data, send_buf->length); 214 DATA_BLOB send_blob; 215 216 struct tevent_context *ev; 217 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 218 if (!tmp_ctx) { 219 return ENOMEM; 220 } 221 222 if (!data) { 223 /* If no event context was available, then create one for this loop */ 224 ev = tevent_context_init(tmp_ctx); 225 if (!ev) { 226 talloc_free(tmp_ctx); 227 return ENOMEM; 228 } 229 } else { 230 ev = talloc_get_type_abort(data, struct tevent_context); 231 } 232 233 send_blob = data_blob_const(send_buf->data, send_buf->length); 223 234 224 235 ret = krb5_krbhst_get_addrinfo(context, hi, &ai); 225 236 if (ret) { 226 return ret; 227 } 228 229 for (a = ai; a; a = ai->ai_next) { 230 smb_krb5 = talloc(NULL, struct smb_krb5_socket); 237 talloc_free(tmp_ctx); 238 return ret; 239 } 240 241 for (a = ai; a; a = a->ai_next) { 242 struct socket_address *remote_addr; 243 smb_krb5 = talloc(tmp_ctx, struct smb_krb5_socket); 231 244 if (!smb_krb5) { 245 talloc_free(tmp_ctx); 232 246 return ENOMEM; 233 247 } 234 248 smb_krb5->hi = hi; 235 249 236 250 switch (a->ai_family) { 237 251 case PF_INET: … … 244 258 #endif 245 259 default: 246 talloc_free( smb_krb5);260 talloc_free(tmp_ctx); 247 261 return EINVAL; 248 262 } 249 263 250 264 status = NT_STATUS_INVALID_PARAMETER; 251 265 switch (hi->proto) { … … 257 271 break; 258 272 case KRB5_KRBHST_HTTP: 259 talloc_free( smb_krb5);273 talloc_free(tmp_ctx); 260 274 return EINVAL; 261 275 } … … 266 280 267 281 talloc_steal(smb_krb5, smb_krb5->sock); 268 269 remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen); 282 283 remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen); 270 284 if (!remote_addr) { 271 285 talloc_free(smb_krb5); … … 278 292 continue; 279 293 } 280 talloc_free(remote_addr);281 294 282 295 /* Setup the FDE, start listening for read events … … 326 339 break; 327 340 case KRB5_KRBHST_HTTP: 328 talloc_free( smb_krb5);341 talloc_free(tmp_ctx); 329 342 return EINVAL; 330 343 } 331 344 while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) { 332 345 if (tevent_loop_once(ev) != 0) { 333 talloc_free( smb_krb5);346 talloc_free(tmp_ctx); 334 347 return EINVAL; 348 } 349 350 /* After each and every event loop, reset the 351 * send_to_kdc pointers to what they were when 352 * we entered this loop. That way, if a 353 * nested event has invalidated them, we put 354 * it back before we return to the heimdal 355 * code */ 356 ret = krb5_set_send_to_kdc_func(context, 357 smb_krb5_send_and_recv_func, 358 data); 359 if (ret != 0) { 360 talloc_free(tmp_ctx); 361 return ret; 335 362 } 336 363 } … … 341 368 342 369 if (!NT_STATUS_IS_OK(smb_krb5->status)) { 343 DEBUG(2,("Error reading smb_krb5 reply packet: %s\n", nt_errstr(smb_krb5->status))); 370 struct tsocket_address *addr = socket_address_to_tsocket_address(smb_krb5, remote_addr); 371 const char *addr_string = NULL; 372 if (addr) { 373 addr_string = tsocket_address_inet_addr_string(addr, smb_krb5); 374 } else { 375 addr_string = NULL; 376 } 377 DEBUG(2,("Error reading smb_krb5 reply packet: %s from %s\n", nt_errstr(smb_krb5->status), 378 addr_string)); 344 379 talloc_free(smb_krb5); 345 380 continue; … … 348 383 ret = krb5_data_copy(recv_buf, smb_krb5->reply.data, smb_krb5->reply.length); 349 384 if (ret) { 350 talloc_free( smb_krb5);385 talloc_free(tmp_ctx); 351 386 return ret; 352 387 } 353 388 talloc_free(smb_krb5); 354 389 355 390 break; 356 391 } 392 talloc_free(tmp_ctx); 357 393 if (a) { 358 394 return 0; … … 361 397 } 362 398 363 krb5_error_code smb_krb5_init_context(void *parent_ctx, 399 krb5_error_code 400 smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, 401 struct loadparm_context *lp_ctx, 402 krb5_context *_krb5_context) 403 { 404 krb5_error_code ret; 405 char **config_files; 406 const char *config_file, *realm; 407 krb5_context krb5_ctx; 408 409 initialize_krb5_error_table(); 410 411 ret = krb5_init_context(&krb5_ctx); 412 if (ret) { 413 DEBUG(1,("krb5_init_context failed (%s)\n", 414 error_message(ret))); 415 return ret; 416 } 417 418 config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf"); 419 if (!config_file) { 420 krb5_free_context(krb5_ctx); 421 return ENOMEM; 422 } 423 424 /* Use our local krb5.conf file by default */ 425 ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files); 426 if (ret) { 427 DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n", 428 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); 429 krb5_free_context(krb5_ctx); 430 return ret; 431 } 432 433 ret = krb5_set_config_files(krb5_ctx, config_files); 434 krb5_free_config_files(config_files); 435 if (ret) { 436 DEBUG(1,("krb5_set_config_files failed (%s)\n", 437 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); 438 krb5_free_context(krb5_ctx); 439 return ret; 440 } 441 442 realm = lpcfg_realm(lp_ctx); 443 if (realm != NULL) { 444 ret = krb5_set_default_realm(krb5_ctx, realm); 445 if (ret) { 446 DEBUG(1,("krb5_set_default_realm failed (%s)\n", 447 smb_get_krb5_error_message(krb5_ctx, ret, tmp_ctx))); 448 krb5_free_context(krb5_ctx); 449 return ret; 450 } 451 } 452 453 *_krb5_context = krb5_ctx; 454 return 0; 455 } 456 457 krb5_error_code smb_krb5_init_context(void *parent_ctx, 364 458 struct tevent_context *ev, 365 459 struct loadparm_context *lp_ctx, 366 struct smb_krb5_context **smb_krb5_context)460 struct smb_krb5_context **smb_krb5_context) 367 461 { 368 462 krb5_error_code ret; 369 463 TALLOC_CTX *tmp_ctx; 370 char **config_files; 371 const char *config_file; 372 464 373 465 initialize_krb5_error_table(); 374 466 375 467 tmp_ctx = talloc_new(parent_ctx); 376 *smb_krb5_context = talloc (tmp_ctx, struct smb_krb5_context);468 *smb_krb5_context = talloc_zero(tmp_ctx, struct smb_krb5_context); 377 469 378 470 if (!*smb_krb5_context || !tmp_ctx) { … … 381 473 } 382 474 383 ret = krb5_init_context(&(*smb_krb5_context)->krb5_context); 384 if (ret) { 385 DEBUG(1,("krb5_init_context failed (%s)\n", 475 ret = smb_krb5_init_context_basic(tmp_ctx, lp_ctx, 476 &(*smb_krb5_context)->krb5_context); 477 if (ret) { 478 DEBUG(1,("smb_krb5_context_init_basic failed (%s)\n", 386 479 error_message(ret))); 387 480 talloc_free(tmp_ctx); 388 481 return ret; 389 }390 391 talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy_1);392 393 config_file = config_path(tmp_ctx, lp_ctx, "krb5.conf");394 if (!config_file) {395 talloc_free(tmp_ctx);396 return ENOMEM;397 }398 399 /* Use our local krb5.conf file by default */400 ret = krb5_prepend_config_files_default(config_file == NULL?"":config_file, &config_files);401 if (ret) {402 DEBUG(1,("krb5_prepend_config_files_default failed (%s)\n",403 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));404 talloc_free(tmp_ctx);405 return ret;406 }407 408 ret = krb5_set_config_files((*smb_krb5_context)->krb5_context,409 config_files);410 krb5_free_config_files(config_files);411 if (ret) {412 DEBUG(1,("krb5_set_config_files failed (%s)\n",413 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));414 talloc_free(tmp_ctx);415 return ret;416 }417 418 if (lp_realm(lp_ctx) && *lp_realm(lp_ctx)) {419 char *upper_realm = strupper_talloc(tmp_ctx, lp_realm(lp_ctx));420 if (!upper_realm) {421 DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(lp_ctx)));422 talloc_free(tmp_ctx);423 return ENOMEM;424 }425 ret = krb5_set_default_realm((*smb_krb5_context)->krb5_context, upper_realm);426 if (ret) {427 DEBUG(1,("krb5_set_default_realm failed (%s)\n",428 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));429 talloc_free(tmp_ctx);430 return ret;431 }432 482 } 433 483 434 484 /* TODO: Should we have a different name here? */ 435 485 ret = krb5_initlog((*smb_krb5_context)->krb5_context, "Samba", &(*smb_krb5_context)->logf); 436 437 if (ret) { 438 DEBUG(1,("krb5_initlog failed (%s)\n", 486 487 if (ret) { 488 DEBUG(1,("krb5_initlog failed (%s)\n", 439 489 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx))); 440 talloc_free(tmp_ctx); 441 return ret; 442 } 443 444 talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy_2); 445 446 ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */, 490 krb5_free_context((*smb_krb5_context)->krb5_context); 491 talloc_free(tmp_ctx); 492 return ret; 493 } 494 495 talloc_set_destructor(*smb_krb5_context, smb_krb5_context_destroy); 496 497 ret = krb5_addlog_func((*smb_krb5_context)->krb5_context, (*smb_krb5_context)->logf, 0 /* min */, -1 /* max */, 447 498 smb_krb5_debug_wrapper, smb_krb5_debug_close, NULL); 448 499 if (ret) { 449 DEBUG(1,("krb5_addlog_func failed (%s)\n", 500 DEBUG(1,("krb5_addlog_func failed (%s)\n", 450 501 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx))); 451 502 talloc_free(tmp_ctx); … … 455 506 456 507 /* Set use of our socket lib */ 457 ret = krb5_set_send_to_kdc_func((*smb_krb5_context)->krb5_context,458 smb_krb5_send_and_recv_func,459 ev);460 if (ret) {461 DEBUG(1,("krb5_set_send_recv_func failed (%s)\n",462 smb_get_krb5_error_message((*smb_krb5_context)->krb5_context, ret, tmp_ctx)));463 talloc_free(tmp_ctx);464 return ret;508 if (ev) { 509 struct tevent_context *previous_ev; 510 ret = smb_krb5_context_set_event_ctx(*smb_krb5_context, 511 ev, &previous_ev); 512 if (ret) { 513 talloc_free(tmp_ctx); 514 return ret; 515 } 465 516 } 466 517 … … 471 522 472 523 krb5_set_dns_canonicalize_hostname((*smb_krb5_context)->krb5_context, 473 lp _parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false));524 lpcfg_parm_bool(lp_ctx, NULL, "krb5", "set_dns_canonicalize", false)); 474 525 475 526 return 0; 476 527 } 477 528 529 krb5_error_code smb_krb5_context_set_event_ctx(struct smb_krb5_context *smb_krb5_context, 530 struct tevent_context *ev, 531 struct tevent_context **previous_ev) 532 { 533 int ret; 534 if (!ev) { 535 return EINVAL; 536 } 537 538 *previous_ev = smb_krb5_context->current_ev; 539 540 smb_krb5_context->current_ev = talloc_reference(smb_krb5_context, ev); 541 if (!smb_krb5_context->current_ev) { 542 return ENOMEM; 543 } 544 545 /* Set use of our socket lib */ 546 ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context, 547 smb_krb5_send_and_recv_func, 548 ev); 549 if (ret) { 550 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 551 DEBUG(1,("krb5_set_send_recv_func failed (%s)\n", 552 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx))); 553 talloc_free(tmp_ctx); 554 talloc_unlink(smb_krb5_context, smb_krb5_context->current_ev); 555 smb_krb5_context->current_ev = NULL; 556 return ret; 557 } 558 return 0; 559 } 560 561 krb5_error_code smb_krb5_context_remove_event_ctx(struct smb_krb5_context *smb_krb5_context, 562 struct tevent_context *previous_ev, 563 struct tevent_context *ev) 564 { 565 int ret; 566 talloc_unlink(smb_krb5_context, ev); 567 /* If there was a mismatch with things happening on a stack, then don't wipe things */ 568 smb_krb5_context->current_ev = previous_ev; 569 /* Set use of our socket lib */ 570 ret = krb5_set_send_to_kdc_func(smb_krb5_context->krb5_context, 571 smb_krb5_send_and_recv_func, 572 previous_ev); 573 if (ret) { 574 TALLOC_CTX *tmp_ctx = talloc_new(NULL); 575 DEBUG(1,("krb5_set_send_recv_func failed (%s)\n", 576 smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, tmp_ctx))); 577 talloc_free(tmp_ctx); 578 return ret; 579 } 580 return 0; 581 } -
vendor/current/source4/auth/kerberos/krb5_init_context.h
r414 r740 21 21 krb5_context krb5_context; 22 22 krb5_log_facility *logf; 23 struct tevent_context *current_ev; 23 24 }; 24 25 25 26 struct tevent_context; 26 27 struct loadparm_context; 28 29 krb5_error_code 30 smb_krb5_init_context_basic(TALLOC_CTX *tmp_ctx, 31 struct loadparm_context *lp_ctx, 32 krb5_context *_krb5_context); 33 27 34 krb5_error_code smb_krb5_init_context(void *parent_ctx, struct tevent_context *ev, 28 35 struct loadparm_context *lp_ctx, 29 36 struct smb_krb5_context **smb_krb5_context); 30 void smb_krb5_free_context(struct smb_krb5_context *smb_krb5_context);31 37 32 38 krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, -
vendor/current/source4/auth/ntlm/auth.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include <tevent.h> 23 #include "../lib/util/tevent_ntstatus.h" 22 24 #include "../lib/util/dlinklist.h" 23 25 #include "auth/auth.h" 24 26 #include "auth/ntlm/auth_proto.h" 25 #include "lib/events/events.h"26 27 #include "param/param.h" 28 #include "dsdb/samdb/samdb.h" 29 27 30 28 31 /*************************************************************************** … … 43 46 Set a fixed challenge 44 47 ***************************************************************************/ 45 bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) 48 _PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) 46 49 { 47 50 return auth_ctx->challenge.may_be_modified; … … 52 55 Returns a const char of length 8 bytes. 53 56 ****************************************************************************/ 54 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal)57 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) 55 58 { 56 59 NTSTATUS nt_status; 57 60 struct auth_method_context *method; 58 61 59 if (auth_ctx->challenge.data.length ) {62 if (auth_ctx->challenge.data.length == 8) { 60 63 DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n", 61 64 auth_ctx->challenge.set_by)); 62 *_chal = auth_ctx->challenge.data.data;65 memcpy(chal, auth_ctx->challenge.data.data, 8); 63 66 return NT_STATUS_OK; 64 67 } 65 68 66 69 for (method = auth_ctx->methods; method; method = method->next) { 67 DATA_BLOB challenge = data_blob(NULL,0); 68 69 nt_status = method->ops->get_challenge(method, auth_ctx, &challenge); 70 nt_status = method->ops->get_challenge(method, auth_ctx, chal); 70 71 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 71 72 continue; … … 74 75 NT_STATUS_NOT_OK_RETURN(nt_status); 75 76 76 if (challenge.length != 8) { 77 DEBUG(0, ("auth_get_challenge: invalid challenge (length %u) by mothod [%s]\n", 78 (unsigned)challenge.length, method->ops->name)); 79 return NT_STATUS_INTERNAL_ERROR; 80 } 81 82 auth_ctx->challenge.data = challenge; 77 auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8); 78 NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data); 83 79 auth_ctx->challenge.set_by = method->ops->name; 84 80 … … 87 83 88 84 if (!auth_ctx->challenge.set_by) { 89 uint8_t chal[8];90 85 generate_random_buffer(chal, 8); 91 86 … … 100 95 auth_ctx->challenge.set_by)); 101 96 102 *_chal = auth_ctx->challenge.data.data;103 97 return NT_STATUS_OK; 104 98 } 105 99 106 100 /**************************************************************************** 107 Try to get a challenge out of the various authentication modules. 108 Returns a const char of length 8 bytes. 101 Used in the gensec_gssapi and gensec_krb5 server-side code, where the 102 PAC isn't available, and for tokenGroups in the DSDB stack. 103 104 Supply either a principal or a DN 109 105 ****************************************************************************/ 110 _PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx, 111 struct auth_context *auth_ctx, 112 const char *principal, 113 struct auth_serversupplied_info **server_info) 106 _PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 107 struct auth_context *auth_ctx, 108 const char *principal, 109 struct ldb_dn *user_dn, 110 struct auth_user_info_dc **user_info_dc) 114 111 { 115 112 NTSTATUS nt_status; … … 117 114 118 115 for (method = auth_ctx->methods; method; method = method->next) { 119 if (!method->ops->get_ server_info_principal) {116 if (!method->ops->get_user_info_dc_principal) { 120 117 continue; 121 118 } 122 119 123 nt_status = method->ops->get_ server_info_principal(mem_ctx, auth_ctx, principal, server_info);120 nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc); 124 121 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 125 122 continue; 126 123 } 127 124 128 NT_STATUS_NOT_OK_RETURN(nt_status); 129 130 break; 131 } 132 133 return NT_STATUS_OK; 134 } 135 136 struct auth_check_password_sync_state { 137 bool finished; 138 NTSTATUS status; 139 struct auth_serversupplied_info *server_info; 140 }; 141 142 static void auth_check_password_sync_callback(struct auth_check_password_request *req, 143 void *private_data) 144 { 145 struct auth_check_password_sync_state *s = talloc_get_type(private_data, 146 struct auth_check_password_sync_state); 147 148 s->finished = true; 149 s->status = auth_check_password_recv(req, s, &s->server_info); 125 return nt_status; 126 } 127 128 return NT_STATUS_NOT_IMPLEMENTED; 150 129 } 151 130 … … 155 134 * 156 135 * Check a user's password, as given in the user_info struct and return various 157 * interesting details in the server_infostruct.158 * 159 * The return value takes precedence over the contents of the server_info136 * interesting details in the user_info_dc struct. 137 * 138 * The return value takes precedence over the contents of the user_info_dc 160 139 * struct. When the return is other than NT_STATUS_OK the contents 161 140 * of that structure is undefined. … … 168 147 * @param user_info Contains the user supplied components, including the passwords. 169 148 * 170 * @param mem_ctx The parent memory context for the server_infostructure171 * 172 * @param server_info If successful, contains information about the authentication,149 * @param mem_ctx The parent memory context for the user_info_dc structure 150 * 151 * @param user_info_dc If successful, contains information about the authentication, 173 152 * including a SAM_ACCOUNT struct describing the user. 174 153 * … … 180 159 TALLOC_CTX *mem_ctx, 181 160 const struct auth_usersupplied_info *user_info, 182 struct auth_serversupplied_info **server_info) 183 { 184 struct auth_check_password_sync_state *sync_state; 161 struct auth_user_info_dc **user_info_dc) 162 { 163 struct tevent_req *subreq; 164 struct tevent_context *ev; 165 bool ok; 185 166 NTSTATUS status; 186 167 187 sync_state = talloc_zero(auth_ctx, struct auth_check_password_sync_state); 188 NT_STATUS_HAVE_NO_MEMORY(sync_state); 189 190 auth_check_password_send(auth_ctx, user_info, auth_check_password_sync_callback, sync_state); 191 192 while (!sync_state->finished) { 193 event_loop_once(auth_ctx->event_ctx); 194 } 195 196 status = sync_state->status; 197 198 if (NT_STATUS_IS_OK(status)) { 199 *server_info = talloc_steal(mem_ctx, sync_state->server_info); 200 } 201 202 talloc_free(sync_state); 168 /*TODO: create a new event context here! */ 169 ev = auth_ctx->event_ctx; 170 171 subreq = auth_check_password_send(mem_ctx, 172 ev, 173 auth_ctx, 174 user_info); 175 if (subreq == NULL) { 176 return NT_STATUS_NO_MEMORY; 177 } 178 179 ok = tevent_req_poll(subreq, ev); 180 if (!ok) { 181 return NT_STATUS_INTERNAL_ERROR; 182 } 183 184 status = auth_check_password_recv(subreq, mem_ctx, user_info_dc); 185 TALLOC_FREE(subreq); 186 203 187 return status; 204 188 } 205 189 206 struct auth_check_password_ request{190 struct auth_check_password_state { 207 191 struct auth_context *auth_ctx; 208 192 const struct auth_usersupplied_info *user_info; 209 struct auth_ serversupplied_info *server_info;193 struct auth_user_info_dc *user_info_dc; 210 194 struct auth_method_context *method; 211 NTSTATUS status;212 struct {213 void (*fn)(struct auth_check_password_request *req, void *private_data);214 void *private_data;215 } callback;216 195 }; 217 196 218 static void auth_check_password_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te, 219 struct timeval t, void *ptr) 220 { 221 struct auth_check_password_request *req = talloc_get_type(ptr, struct auth_check_password_request); 222 req->status = req->method->ops->check_password(req->method, req, req->user_info, &req->server_info); 223 req->callback.fn(req, req->callback.private_data); 224 } 225 197 static void auth_check_password_async_trigger(struct tevent_context *ev, 198 struct tevent_immediate *im, 199 void *private_data); 226 200 /** 227 201 * Check a user's Plaintext, LM or NTLM password. … … 229 203 * 230 204 * Check a user's password, as given in the user_info struct and return various 231 * interesting details in the server_infostruct.232 * 233 * The return value takes precedence over the contents of the server_info205 * interesting details in the user_info_dc struct. 206 * 207 * The return value takes precedence over the contents of the user_info_dc 234 208 * struct. When the return is other than NT_STATUS_OK the contents 235 209 * of that structure is undefined. 210 * 211 * @param mem_ctx The memory context the request should operate on 212 * 213 * @param ev The tevent context the request should operate on 236 214 * 237 215 * @param auth_ctx Supplies the challenges and some other data. … … 242 220 * @param user_info Contains the user supplied components, including the passwords. 243 221 * 244 * @param callback A callback function which will be called when the operation is finished. 245 * The callback function needs to call auth_check_password_recv() to get the return values 246 * 247 * @param private_data A private pointer which will ba passed to the callback function 222 * @return The request handle or NULL on no memory error. 248 223 * 249 224 **/ 250 225 251 _PUBLIC_ void auth_check_password_send(struct auth_context *auth_ctx, 252 const struct auth_usersupplied_info *user_info, 253 void (*callback)(struct auth_check_password_request *req, void *private_data), 254 void *private_data) 255 { 226 _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, 227 struct tevent_context *ev, 228 struct auth_context *auth_ctx, 229 const struct auth_usersupplied_info *user_info) 230 { 231 struct tevent_req *req; 232 struct auth_check_password_state *state; 256 233 /* if all the modules say 'not for me' this is reasonable */ 257 234 NTSTATUS nt_status; 235 uint8_t chal[8]; 236 struct auth_usersupplied_info *user_info_tmp; 237 struct tevent_immediate *im; 238 239 DEBUG(3,("auth_check_password_send: " 240 "Checking password for unmapped user [%s]\\[%s]@[%s]\n", 241 user_info->client.domain_name, user_info->client.account_name, 242 user_info->workstation_name)); 243 244 req = tevent_req_create(mem_ctx, &state, 245 struct auth_check_password_state); 246 if (req == NULL) { 247 return NULL; 248 } 249 250 state->auth_ctx = auth_ctx; 251 state->user_info = user_info; 252 253 if (!user_info->mapped_state) { 254 nt_status = map_user_info(req, lpcfg_workgroup(auth_ctx->lp_ctx), 255 user_info, &user_info_tmp); 256 if (tevent_req_nterror(req, nt_status)) { 257 return tevent_req_post(req, ev); 258 } 259 user_info = user_info_tmp; 260 state->user_info = user_info_tmp; 261 } 262 263 DEBUGADD(3,("auth_check_password_send: " 264 "mapped user is: [%s]\\[%s]@[%s]\n", 265 user_info->mapped.domain_name, 266 user_info->mapped.account_name, 267 user_info->workstation_name)); 268 269 nt_status = auth_get_challenge(auth_ctx, chal); 270 if (tevent_req_nterror(req, nt_status)) { 271 DEBUG(0,("auth_check_password_send: " 272 "Invalid challenge (length %u) stored for " 273 "this auth context set_by %s - cannot continue: %s\n", 274 (unsigned)auth_ctx->challenge.data.length, 275 auth_ctx->challenge.set_by, 276 nt_errstr(nt_status))); 277 return tevent_req_post(req, ev); 278 } 279 280 if (auth_ctx->challenge.set_by) { 281 DEBUG(10,("auth_check_password_send: " 282 "auth_context challenge created by %s\n", 283 auth_ctx->challenge.set_by)); 284 } 285 286 DEBUG(10, ("auth_check_password_send: challenge is: \n")); 287 dump_data(5, auth_ctx->challenge.data.data, 288 auth_ctx->challenge.data.length); 289 290 im = tevent_create_immediate(state); 291 if (tevent_req_nomem(im, req)) { 292 return tevent_req_post(req, ev); 293 } 294 295 tevent_schedule_immediate(im, 296 auth_ctx->event_ctx, 297 auth_check_password_async_trigger, 298 req); 299 return req; 300 } 301 302 static void auth_check_password_async_trigger(struct tevent_context *ev, 303 struct tevent_immediate *im, 304 void *private_data) 305 { 306 struct tevent_req *req = 307 talloc_get_type_abort(private_data, struct tevent_req); 308 struct auth_check_password_state *state = 309 tevent_req_data(req, struct auth_check_password_state); 310 NTSTATUS status; 258 311 struct auth_method_context *method; 259 const uint8_t *challenge; 260 struct auth_usersupplied_info *user_info_tmp; 261 struct auth_check_password_request *req = NULL; 262 263 DEBUG(3, ("auth_check_password_send: Checking password for unmapped user [%s]\\[%s]@[%s]\n", 264 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 265 266 req = talloc_zero(auth_ctx, struct auth_check_password_request); 267 if (!req) { 268 callback(NULL, private_data); 312 313 status = NT_STATUS_OK; 314 315 for (method=state->auth_ctx->methods; method; method = method->next) { 316 317 /* we fill in state->method here so debug messages in 318 the callers know which method failed */ 319 state->method = method; 320 321 /* check if the module wants to check the password */ 322 status = method->ops->want_check(method, req, state->user_info); 323 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 324 DEBUG(11,("auth_check_password_send: " 325 "%s had nothing to say\n", 326 method->ops->name)); 327 continue; 328 } 329 330 if (tevent_req_nterror(req, status)) { 331 return; 332 } 333 334 status = method->ops->check_password(method, 335 state, 336 state->user_info, 337 &state->user_info_dc); 338 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 339 /* the backend has handled the request */ 340 break; 341 } 342 } 343 344 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { 345 /* don't expose the NT_STATUS_NOT_IMPLEMENTED 346 internals */ 347 status = NT_STATUS_NO_SUCH_USER; 348 } 349 350 if (tevent_req_nterror(req, status)) { 269 351 return; 270 352 } 271 req->auth_ctx = auth_ctx; 272 req->user_info = user_info; 273 req->callback.fn = callback; 274 req->callback.private_data = private_data; 275 276 if (!user_info->mapped_state) { 277 nt_status = map_user_info(req, lp_workgroup(auth_ctx->lp_ctx), user_info, &user_info_tmp); 278 if (!NT_STATUS_IS_OK(nt_status)) goto failed; 279 user_info = user_info_tmp; 280 req->user_info = user_info_tmp; 281 } 282 283 DEBUGADD(3,("auth_check_password_send: mapped user is: [%s]\\[%s]@[%s]\n", 284 user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name)); 285 286 nt_status = auth_get_challenge(auth_ctx, &challenge); 287 if (!NT_STATUS_IS_OK(nt_status)) { 288 DEBUG(0, ("auth_check_password_send: Invalid challenge (length %u) stored for this auth context set_by %s - cannot continue: %s\n", 289 (unsigned)auth_ctx->challenge.data.length, auth_ctx->challenge.set_by, nt_errstr(nt_status))); 290 goto failed; 291 } 292 293 if (auth_ctx->challenge.set_by) { 294 DEBUG(10, ("auth_check_password_send: auth_context challenge created by %s\n", 295 auth_ctx->challenge.set_by)); 296 } 297 298 DEBUG(10, ("auth_check_password_send: challenge is: \n")); 299 dump_data(5, auth_ctx->challenge.data.data, auth_ctx->challenge.data.length); 300 301 nt_status = NT_STATUS_NO_SUCH_USER; /* If all the modules say 'not for me', then this is reasonable */ 302 for (method = auth_ctx->methods; method; method = method->next) { 303 NTSTATUS result; 304 struct tevent_timer *te = NULL; 305 306 /* check if the module wants to chek the password */ 307 result = method->ops->want_check(method, req, user_info); 308 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) { 309 DEBUG(11,("auth_check_password_send: %s had nothing to say\n", method->ops->name)); 310 continue; 311 } 312 313 nt_status = result; 314 req->method = method; 315 316 if (!NT_STATUS_IS_OK(nt_status)) break; 317 318 te = event_add_timed(auth_ctx->event_ctx, req, 319 timeval_zero(), 320 auth_check_password_async_timed_handler, req); 321 if (!te) { 322 nt_status = NT_STATUS_NO_MEMORY; 323 goto failed; 324 } 325 return; 326 } 327 328 failed: 329 req->status = nt_status; 330 req->callback.fn(req, req->callback.private_data); 353 354 tevent_req_done(req); 331 355 } 332 356 … … 335 359 * async receive function 336 360 * 337 * The return value takes precedence over the contents of the server_info361 * The return value takes precedence over the contents of the user_info_dc 338 362 * struct. When the return is other than NT_STATUS_OK the contents 339 363 * of that structure is undefined. 340 364 * 341 365 * 342 * @param req The async auth_check_password state, passes to the callers callback function343 * 344 * @param mem_ctx The parent memory context for the server_infostructure345 * 346 * @param server_info If successful, contains information about the authentication,366 * @param req The async request state 367 * 368 * @param mem_ctx The parent memory context for the user_info_dc structure 369 * 370 * @param user_info_dc If successful, contains information about the authentication, 347 371 * including a SAM_ACCOUNT struct describing the user. 348 372 * … … 351 375 **/ 352 376 353 _PUBLIC_ NTSTATUS auth_check_password_recv(struct auth_check_password_request*req,377 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, 354 378 TALLOC_CTX *mem_ctx, 355 struct auth_serversupplied_info **server_info) 356 { 379 struct auth_user_info_dc **user_info_dc) 380 { 381 struct auth_check_password_state *state = 382 tevent_req_data(req, struct auth_check_password_state); 357 383 NTSTATUS status; 358 384 359 NT_STATUS_HAVE_NO_MEMORY(req); 360 361 if (NT_STATUS_IS_OK(req->status)) { 362 DEBUG(5,("auth_check_password_recv: %s authentication for user [%s\\%s] succeeded\n", 363 req->method->ops->name, req->server_info->domain_name, req->server_info->account_name)); 364 365 *server_info = talloc_steal(mem_ctx, req->server_info); 366 } else { 367 DEBUG(2,("auth_check_password_recv: %s authentication for user [%s\\%s] FAILED with error %s\n", 368 (req->method ? req->method->ops->name : "NO_METHOD"), 369 req->user_info->mapped.domain_name, 370 req->user_info->mapped.account_name, 371 nt_errstr(req->status))); 372 } 373 374 status = req->status; 375 talloc_free(req); 376 return status; 385 if (tevent_req_is_nterror(req, &status)) { 386 DEBUG(2,("auth_check_password_recv: " 387 "%s authentication for user [%s\\%s] " 388 "FAILED with error %s\n", 389 (state->method ? state->method->ops->name : "NO_METHOD"), 390 state->user_info->mapped.domain_name, 391 state->user_info->mapped.account_name, 392 nt_errstr(status))); 393 tevent_req_received(req); 394 return status; 395 } 396 397 DEBUG(5,("auth_check_password_recv: " 398 "%s authentication for user [%s\\%s] succeeded\n", 399 state->method->ops->name, 400 state->user_info_dc->info->domain_name, 401 state->user_info_dc->info->account_name)); 402 403 *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc); 404 405 tevent_req_received(req); 406 return NT_STATUS_OK; 407 } 408 409 /* Wrapper because we don't want to expose all callers to needing to 410 * know that session_info is generated from the main ldb */ 411 static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx, 412 struct auth_context *auth_context, 413 struct auth_user_info_dc *user_info_dc, 414 uint32_t session_info_flags, 415 struct auth_session_info **session_info) 416 { 417 return auth_generate_session_info(mem_ctx, auth_context->lp_ctx, 418 auth_context->sam_ctx, user_info_dc, 419 session_info_flags, session_info); 377 420 } 378 421 379 422 /*************************************************************************** 380 423 Make a auth_info struct for the auth subsystem 381 - Allow the caller to specify the methods to use 424 - Allow the caller to specify the methods to use, including optionally the SAM to use 382 425 ***************************************************************************/ 383 426 _PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods, 384 struct tevent_context *ev, 385 struct messaging_context *msg, 386 struct loadparm_context *lp_ctx, 387 struct auth_context **auth_ctx) 427 struct tevent_context *ev, 428 struct messaging_context *msg, 429 struct loadparm_context *lp_ctx, 430 struct ldb_context *sam_ctx, 431 struct auth_context **auth_ctx) 388 432 { 389 433 int i; 390 434 struct auth_context *ctx; 391 435 392 auth_init(); 393 394 if (!methods) { 395 DEBUG(0,("auth_context_create: No auth method list!?\n")); 396 return NT_STATUS_INTERNAL_ERROR; 397 } 436 auth4_init(); 398 437 399 438 if (!ev) { 400 439 DEBUG(0,("auth_context_create: called with out event context\n")); 401 return NT_STATUS_INTERNAL_ERROR;402 }403 404 if (!msg) {405 DEBUG(0,("auth_context_create: called with out messaging context\n"));406 440 return NT_STATUS_INTERNAL_ERROR; 407 441 } … … 417 451 ctx->lp_ctx = lp_ctx; 418 452 419 for (i=0; methods[i] ; i++) { 453 if (sam_ctx) { 454 ctx->sam_ctx = sam_ctx; 455 } else { 456 ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0); 457 } 458 459 for (i=0; methods && methods[i] ; i++) { 420 460 struct auth_method_context *method; 421 461 … … 434 474 } 435 475 436 if (!ctx->methods) {437 return NT_STATUS_INTERNAL_ERROR;438 }439 440 476 ctx->check_password = auth_check_password; 441 477 ctx->get_challenge = auth_get_challenge; 442 478 ctx->set_challenge = auth_context_set_challenge; 443 479 ctx->challenge_may_be_modified = auth_challenge_may_be_modified; 444 ctx->get_server_info_principal = auth_get_server_info_principal; 480 ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal; 481 ctx->generate_session_info = auth_generate_session_info_wrapper; 445 482 446 483 *auth_ctx = ctx; … … 448 485 return NT_STATUS_OK; 449 486 } 487 488 const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 489 { 490 const char **auth_methods = NULL; 491 switch (lpcfg_server_role(lp_ctx)) { 492 case ROLE_STANDALONE: 493 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL); 494 break; 495 case ROLE_DOMAIN_MEMBER: 496 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL); 497 break; 498 case ROLE_DOMAIN_CONTROLLER: 499 auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); 500 break; 501 } 502 return auth_methods; 503 } 504 450 505 /*************************************************************************** 451 506 Make a auth_info struct for the auth subsystem 452 507 - Uses default auth_methods, depending on server role and smb.conf settings 453 508 ***************************************************************************/ 454 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 509 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 455 510 struct tevent_context *ev, 456 511 struct messaging_context *msg, … … 458 513 struct auth_context **auth_ctx) 459 514 { 460 const char **auth_methods = NULL; 461 switch (lp_server_role(lp_ctx)) { 462 case ROLE_STANDALONE: 463 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL); 464 break; 465 case ROLE_DOMAIN_MEMBER: 466 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL); 467 break; 468 case ROLE_DOMAIN_CONTROLLER: 469 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL); 470 break; 471 } 472 return auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, auth_ctx); 473 } 474 515 NTSTATUS status; 516 const char **auth_methods; 517 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 518 if (!tmp_ctx) { 519 return NT_STATUS_NO_MEMORY; 520 } 521 522 auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx); 523 if (!auth_methods) { 524 return NT_STATUS_INVALID_PARAMETER; 525 } 526 status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx); 527 talloc_free(tmp_ctx); 528 return status; 529 } 530 531 /* Create an auth context from an open LDB. 532 533 This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups) 534 535 */ 536 NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx) 537 { 538 NTSTATUS status; 539 const char **auth_methods; 540 struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context); 541 struct tevent_context *ev = ldb_get_event_context(ldb); 542 543 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 544 if (!tmp_ctx) { 545 return NT_STATUS_NO_MEMORY; 546 } 547 548 auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx); 549 if (!auth_methods) { 550 return NT_STATUS_INVALID_PARAMETER; 551 } 552 status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx); 553 talloc_free(tmp_ctx); 554 return status; 555 } 475 556 476 557 /* the list of currently registered AUTH backends */ … … 545 626 sizeof(struct auth_context), 546 627 sizeof(struct auth_usersupplied_info), 547 sizeof(struct auth_ serversupplied_info)628 sizeof(struct auth_user_info_dc) 548 629 }; 549 630 … … 551 632 } 552 633 553 _PUBLIC_ NTSTATUS auth _init(void)634 _PUBLIC_ NTSTATUS auth4_init(void) 554 635 { 555 636 static bool initialized = false; 556 extern NTSTATUS auth_developer_init(void); 557 extern NTSTATUS auth_winbind_init(void); 558 extern NTSTATUS auth_anonymous_init(void); 559 extern NTSTATUS auth_unix_init(void); 560 extern NTSTATUS auth_sam_init(void); 561 extern NTSTATUS auth_server_init(void); 562 563 init_module_fn static_init[] = { STATIC_auth_MODULES }; 637 #define _MODULE_PROTO(init) extern NTSTATUS init(void); 638 STATIC_auth4_MODULES_PROTO; 639 init_module_fn static_init[] = { STATIC_auth4_MODULES }; 564 640 565 641 if (initialized) return NT_STATUS_OK; … … 570 646 return NT_STATUS_OK; 571 647 } 572 573 NTSTATUS server_service_auth_init(void)574 {575 return auth_init();576 } -
vendor/current/source4/auth/ntlm/auth_anonymous.c
r414 r740 53 53 TALLOC_CTX *mem_ctx, 54 54 const struct auth_usersupplied_info *user_info, 55 struct auth_ serversupplied_info **_server_info)55 struct auth_user_info_dc **_user_info_dc) 56 56 { 57 return auth_anonymous_ server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), _server_info);57 return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc); 58 58 } 59 59 -
vendor/current/source4/auth/ntlm/auth_developer.c
r414 r740 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #include "libcli/security/security.h" 26 #include "librpc/gen_ndr/ndr_samr.h"27 26 28 27 static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, … … 49 48 TALLOC_CTX *mem_ctx, 50 49 const struct auth_usersupplied_info *user_info, 51 struct auth_ serversupplied_info **_server_info)50 struct auth_user_info_dc **_user_info_dc) 52 51 { 53 52 NTSTATUS nt_status; 54 struct auth_serversupplied_info *server_info; 53 struct auth_user_info_dc *user_info_dc; 54 struct auth_user_info *info; 55 55 uint32_t error_num; 56 56 const char *user; … … 67 67 NT_STATUS_NOT_OK_RETURN(nt_status); 68 68 69 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 70 NT_STATUS_HAVE_NO_MEMORY(server_info); 71 72 server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS); 73 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 74 75 /* is this correct? */ 76 server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS); 77 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 78 79 server_info->n_domain_groups = 0; 80 server_info->domain_groups = NULL; 69 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 70 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 71 72 /* This returns a pointer to a struct dom_sid, which is the 73 * same as a 1 element list of struct dom_sid */ 74 user_info_dc->num_sids = 1; 75 user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS); 76 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); 81 77 82 78 /* annoying, but the Anonymous really does have a session key, 83 79 and it is all zeros! */ 84 server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); 85 NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); 86 87 server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); 88 NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); 89 90 data_blob_clear(&server_info->user_session_key); 91 data_blob_clear(&server_info->lm_session_key); 92 93 server_info->account_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user); 94 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 95 96 server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY"); 97 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 98 99 server_info->full_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s Anonymous Logon", user); 100 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 101 102 server_info->logon_script = talloc_strdup(server_info, ""); 103 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 104 105 server_info->profile_path = talloc_strdup(server_info, ""); 106 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 107 108 server_info->home_directory = talloc_strdup(server_info, ""); 109 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 110 111 server_info->home_drive = talloc_strdup(server_info, ""); 112 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 113 114 server_info->last_logon = 0; 115 server_info->last_logoff = 0; 116 server_info->acct_expiry = 0; 117 server_info->last_password_change = 0; 118 server_info->allow_password_change = 0; 119 server_info->force_password_change = 0; 120 121 server_info->logon_count = 0; 122 server_info->bad_password_count = 0; 123 124 server_info->acct_flags = ACB_NORMAL; 125 126 server_info->authenticated = false; 127 128 *_server_info = server_info; 80 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); 81 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); 82 83 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); 84 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); 85 86 data_blob_clear(&user_info_dc->user_session_key); 87 data_blob_clear(&user_info_dc->lm_session_key); 88 89 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 90 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 91 92 info->account_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user); 93 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 94 95 info->domain_name = talloc_strdup(user_info_dc, "NT AUTHORITY"); 96 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 97 98 info->full_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s Anonymous Logon", user); 99 NT_STATUS_HAVE_NO_MEMORY(info->full_name); 100 101 info->logon_script = talloc_strdup(user_info_dc, ""); 102 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 103 104 info->profile_path = talloc_strdup(user_info_dc, ""); 105 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 106 107 info->home_directory = talloc_strdup(user_info_dc, ""); 108 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 109 110 info->home_drive = talloc_strdup(user_info_dc, ""); 111 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 112 113 info->last_logon = 0; 114 info->last_logoff = 0; 115 info->acct_expiry = 0; 116 info->last_password_change = 0; 117 info->allow_password_change = 0; 118 info->force_password_change = 0; 119 120 info->logon_count = 0; 121 info->bad_password_count = 0; 122 123 info->acct_flags = ACB_NORMAL; 124 125 info->authenticated = true; 126 127 *_user_info_dc = user_info_dc; 129 128 130 129 return nt_status; … … 152 151 * @return NT_STATUS_UNSUCCESSFUL 153 152 **/ 154 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob) 155 { 156 DATA_BLOB blob; 153 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 154 { 157 155 const char *challenge = "I am a teapot"; 158 156 159 blob = data_blob_talloc(mem_ctx, challenge, 8); 160 NT_STATUS_HAVE_NO_MEMORY(blob.data); 161 162 *_blob = blob; 157 memcpy(chal, challenge, 8); 158 163 159 return NT_STATUS_OK; 164 160 } … … 175 171 TALLOC_CTX *mem_ctx, 176 172 const struct auth_usersupplied_info *user_info, 177 struct auth_ serversupplied_info **_server_info)173 struct auth_user_info_dc **_user_info_dc) 178 174 { 179 175 /* don't handle any users */ -
vendor/current/source4/auth/ntlm/auth_sam.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "librpc/gen_ndr/ndr_netlogon.h"24 23 #include "system/time.h" 25 #include "lib/ldb/include/ldb.h" 26 #include "../lib/util/util_ldb.h" 24 #include <ldb.h> 25 #include "libcli/ldap/ldap_ndr.h" 26 #include "libcli/security/security.h" 27 27 #include "auth/auth.h" 28 28 #include "../libcli/auth/ntlm_check.h" … … 30 30 #include "auth/auth_sam.h" 31 31 #include "dsdb/samdb/samdb.h" 32 #include "libcli/security/security.h" 33 #include "libcli/ldap/ldap_ndr.h" 32 #include "dsdb/common/util.h" 34 33 #include "param/param.h" 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 #include "lib/messaging/irpc.h" 35 36 36 37 extern const char *user_attrs[]; … … 49 50 50 51 /* pull the user attributes */ 51 ret = gendb_search_single_extended_dn(sam_ctx, mem_ctx, domain_dn, LDB_SCOPE_SUBTREE, 52 ret_msg, user_attrs, 53 "(&(sAMAccountName=%s)(objectclass=user))", 54 ldb_binary_encode_string(mem_ctx, account_name)); 52 ret = dsdb_search_one(sam_ctx, mem_ctx, ret_msg, domain_dn, LDB_SCOPE_SUBTREE, 53 user_attrs, 54 DSDB_SEARCH_SHOW_EXTENDED_DN, 55 "(&(sAMAccountName=%s)(objectclass=user))", 56 ldb_binary_encode_string(mem_ctx, account_name)); 55 57 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 56 58 DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n", … … 99 101 *user_sess_key = data_blob(NULL, 0); 100 102 status = hash_password_check(mem_ctx, 101 lp _lanman_auth(auth_context->lp_ctx),103 lpcfg_lanman_auth(auth_context->lp_ctx), 102 104 user_info->password.hash.lanman, 103 105 user_info->password.hash.nt, … … 109 111 case AUTH_PASSWORD_RESPONSE: 110 112 status = ntlm_password_check(mem_ctx, 111 lp _lanman_auth(auth_context->lp_ctx),112 lp _ntlm_auth(auth_context->lp_ctx),113 lpcfg_lanman_auth(auth_context->lp_ctx), 114 lpcfg_ntlm_auth(auth_context->lp_ctx), 113 115 user_info->logon_parameters, 114 116 &auth_context->challenge.data, … … 135 137 136 138 139 /* 140 send a message to the drepl server telling it to initiate a 141 REPL_SECRET getncchanges extended op to fetch the users secrets 142 */ 143 static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context, 144 struct ldb_dn *user_dn) 145 { 146 struct dcerpc_binding_handle *irpc_handle; 147 struct drepl_trigger_repl_secret r; 148 struct tevent_req *req; 149 150 irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx, 151 "dreplsrv", 152 &ndr_table_irpc); 153 if (irpc_handle == NULL) { 154 DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n")); 155 return; 156 } 157 158 r.in.user_dn = ldb_dn_get_linearized(user_dn); 159 160 req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx, 161 auth_context->event_ctx, 162 irpc_handle, 163 &r); 164 165 /* we aren't interested in a reply */ 166 talloc_free(req); 167 talloc_free(irpc_handle); 168 } 169 137 170 138 171 static NTSTATUS authsam_authenticate(struct auth_context *auth_context, … … 146 179 NTSTATUS nt_status; 147 180 148 uint16_t acct_flags = samdb_result_acct_flags( sam_ctx, mem_ctx, msg, domain_dn);181 uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn); 149 182 150 183 /* Quit if the account was locked out. */ … … 165 198 NT_STATUS_NOT_OK_RETURN(nt_status); 166 199 200 if (lm_pwd == NULL && nt_pwd == NULL) { 201 bool am_rodc; 202 if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) { 203 /* we don't have passwords for this 204 * account. We are an RODC, and this account 205 * may be one for which we either are denied 206 * REPL_SECRET replication or we haven't yet 207 * done the replication. We return 208 * NT_STATUS_NOT_IMPLEMENTED which tells the 209 * auth code to try the next authentication 210 * mechanism. We also send a message to our 211 * drepl server to tell it to try and 212 * replicate the secrets for this account. 213 */ 214 auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn); 215 return NT_STATUS_NOT_IMPLEMENTED; 216 } 217 } 218 167 219 nt_status = authsam_password_ok(auth_context, mem_ctx, 168 220 acct_flags, lm_pwd, nt_pwd, … … 170 222 NT_STATUS_NOT_OK_RETURN(nt_status); 171 223 172 nt_status = authsam_account_ok(mem_ctx, sam_ctx,224 nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx, 173 225 user_info->logon_parameters, 174 226 domain_dn, … … 186 238 TALLOC_CTX *mem_ctx, 187 239 const struct auth_usersupplied_info *user_info, 188 struct auth_ serversupplied_info **server_info)240 struct auth_user_info_dc **user_info_dc) 189 241 { 190 242 NTSTATUS nt_status; 191 243 const char *account_name = user_info->mapped.account_name; 192 244 struct ldb_message *msg; 193 struct ldb_context *sam_ctx;194 245 struct ldb_dn *domain_dn; 195 246 DATA_BLOB user_sess_key, lm_sess_key; 196 247 TALLOC_CTX *tmp_ctx; 197 248 249 if (ctx->auth_ctx->sam_ctx == NULL) { 250 DEBUG(0, ("No SAM available, cannot log in users\n")); 251 return NT_STATUS_INVALID_SYSTEM_SERVICE; 252 } 253 198 254 if (!account_name || !*account_name) { 199 255 /* 'not for me' */ … … 206 262 } 207 263 208 sam_ctx = samdb_connect(tmp_ctx, ctx->auth_ctx->event_ctx, ctx->auth_ctx->lp_ctx, system_session(mem_ctx, ctx->auth_ctx->lp_ctx)); 209 if (sam_ctx == NULL) { 210 talloc_free(tmp_ctx); 211 return NT_STATUS_INVALID_SYSTEM_SERVICE; 212 } 213 214 domain_dn = ldb_get_default_basedn(sam_ctx); 264 domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx); 215 265 if (domain_dn == NULL) { 216 266 talloc_free(tmp_ctx); … … 218 268 } 219 269 220 nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msg);270 nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg); 221 271 if (!NT_STATUS_IS_OK(nt_status)) { 222 272 talloc_free(tmp_ctx); … … 224 274 } 225 275 226 nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msg, user_info,276 nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info, 227 277 &user_sess_key, &lm_sess_key); 228 278 if (!NT_STATUS_IS_OK(nt_status)) { … … 231 281 } 232 282 233 nt_status = authsam_make_ server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),234 lp_sam_name(ctx->auth_ctx->lp_ctx),283 nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), 284 lpcfg_sam_name(ctx->auth_ctx->lp_ctx), 235 285 domain_dn, 236 286 msg, 237 287 user_sess_key, lm_sess_key, 238 server_info);288 user_info_dc); 239 289 if (!NT_STATUS_IS_OK(nt_status)) { 240 290 talloc_free(tmp_ctx); … … 242 292 } 243 293 244 talloc_steal(mem_ctx, * server_info);294 talloc_steal(mem_ctx, *user_info_dc); 245 295 talloc_free(tmp_ctx); 246 296 … … 272 322 } 273 323 274 is_local_name = lp _is_myname(ctx->auth_ctx->lp_ctx,324 is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx, 275 325 user_info->mapped.domain_name); 276 is_my_domain = lp _is_mydomain(ctx->auth_ctx->lp_ctx,326 is_my_domain = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, 277 327 user_info->mapped.domain_name); 278 328 279 329 /* check whether or not we service this domain/workgroup name */ 280 switch (lp _server_role(ctx->auth_ctx->lp_ctx)) {330 switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) { 281 331 case ROLE_STANDALONE: 282 332 return NT_STATUS_OK; … … 299 349 } 300 350 301 DEBUG(6,("authsam_check_password: lp _server_role() has an undefined value\n"));351 DEBUG(6,("authsam_check_password: lpcfg_server_role() has an undefined value\n")); 302 352 return NT_STATUS_NOT_IMPLEMENTED; 303 353 } 304 354 305 355 306 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */ 307 NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx, 308 struct auth_context *auth_context, 309 const char *principal, 310 struct auth_serversupplied_info **server_info) 311 { 312 NTSTATUS nt_status; 313 DATA_BLOB user_sess_key = data_blob(NULL, 0); 314 DATA_BLOB lm_sess_key = data_blob(NULL, 0); 315 316 struct ldb_message *msg; 317 struct ldb_context *sam_ctx; 318 struct ldb_dn *domain_dn; 319 320 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 321 if (!tmp_ctx) { 322 return NT_STATUS_NO_MEMORY; 323 } 324 325 sam_ctx = samdb_connect(tmp_ctx, auth_context->event_ctx, auth_context->lp_ctx, 326 system_session(tmp_ctx, auth_context->lp_ctx)); 327 if (sam_ctx == NULL) { 328 talloc_free(tmp_ctx); 329 return NT_STATUS_INVALID_SYSTEM_SERVICE; 330 } 331 332 nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, 333 user_attrs, &domain_dn, &msg); 334 if (!NT_STATUS_IS_OK(nt_status)) { 335 return nt_status; 336 } 337 338 nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, 339 lp_netbios_name(auth_context->lp_ctx), 340 lp_workgroup(auth_context->lp_ctx), 341 domain_dn, 342 msg, 343 user_sess_key, lm_sess_key, 344 server_info); 345 if (NT_STATUS_IS_OK(nt_status)) { 346 talloc_steal(mem_ctx, *server_info); 347 } 348 talloc_free(tmp_ctx); 349 return nt_status; 350 } 351 356 /* Wrapper for the auth subsystem pointer */ 357 static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx, 358 struct auth_context *auth_context, 359 const char *principal, 360 struct ldb_dn *user_dn, 361 struct auth_user_info_dc **user_info_dc) 362 { 363 return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx, 364 principal, user_dn, user_info_dc); 365 } 352 366 static const struct auth_operations sam_ignoredomain_ops = { 353 367 .name = "sam_ignoredomain", … … 355 369 .want_check = authsam_ignoredomain_want_check, 356 370 .check_password = authsam_check_password_internals, 357 .get_ server_info_principal = authsam_get_server_info_principal371 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 358 372 }; 359 373 … … 363 377 .want_check = authsam_want_check, 364 378 .check_password = authsam_check_password_internals, 365 .get_ server_info_principal = authsam_get_server_info_principal379 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 366 380 }; 367 381 -
vendor/current/source4/auth/ntlm/auth_server.c
r414 r740 22 22 #include "includes.h" 23 23 #include "auth/auth.h" 24 #include "auth/ntlm/auth_proto.h"25 24 #include "auth/credentials/credentials.h" 26 25 #include "libcli/security/security.h" 27 #include "librpc/gen_ndr/ndr_samr.h"28 26 #include "libcli/smb_composite/smb_composite.h" 29 27 #include "param/param.h" … … 43 41 * The challenge from the target server, when operating in security=server 44 42 **/ 45 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)43 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 46 44 { 47 45 struct smb_composite_connect io; … … 52 50 /* Make a connection to the target server, found by 'password server' in smb.conf */ 53 51 54 lp _smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);52 lpcfg_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options); 55 53 56 54 /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */ … … 58 56 59 57 /* Hope we don't get * (the default), as this won't work... */ 60 host_list = lp _passwordserver(ctx->auth_ctx->lp_ctx);58 host_list = lpcfg_passwordserver(ctx->auth_ctx->lp_ctx); 61 59 if (!host_list) { 62 60 return NT_STATUS_INTERNAL_ERROR; … … 66 64 return NT_STATUS_INTERNAL_ERROR; 67 65 } 68 io.in.dest_ports = lp _smb_ports(ctx->auth_ctx->lp_ctx);69 io.in.socket_options = lp _socket_options(ctx->auth_ctx->lp_ctx);70 io.in.gensec_settings = lp _gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);66 io.in.dest_ports = lpcfg_smb_ports(ctx->auth_ctx->lp_ctx); 67 io.in.socket_options = lpcfg_socket_options(ctx->auth_ctx->lp_ctx); 68 io.in.gensec_settings = lpcfg_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx); 71 69 72 70 io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host); … … 75 73 io.in.credentials = cli_credentials_init_anon(mem_ctx); 76 74 cli_credentials_set_workstation(io.in.credentials, 77 lp _netbios_name(ctx->auth_ctx->lp_ctx),75 lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), 78 76 CRED_SPECIFIED); 79 77 … … 84 82 io.in.options = smb_options; 85 83 86 io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx); 87 lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options); 88 89 status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx), 84 lpcfg_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options); 85 86 status = smb_composite_connect(&io, mem_ctx, lpcfg_resolve_context(ctx->auth_ctx->lp_ctx), 90 87 ctx->auth_ctx->event_ctx); 91 88 NT_STATUS_NOT_OK_RETURN(status); 92 89 93 *_blob = io.out.tree->session->transport->negotiate.secblob; 90 if (io.out.tree->session->transport->negotiate.secblob.length != 8) { 91 return NT_STATUS_INTERNAL_ERROR; 92 } 93 memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8); 94 94 ctx->private_data = talloc_steal(ctx, io.out.tree->session); 95 95 return NT_STATUS_OK; … … 112 112 TALLOC_CTX *mem_ctx, 113 113 const struct auth_usersupplied_info *user_info, 114 struct auth_ serversupplied_info **_server_info)114 struct auth_user_info_dc **_user_info_dc) 115 115 { 116 116 NTSTATUS nt_status; 117 struct auth_serversupplied_info *server_info; 117 struct auth_user_info_dc *user_info_dc; 118 struct auth_user_info *info; 118 119 struct cli_credentials *creds; 119 120 struct smb_composite_sesssetup session_setup; … … 148 149 session_setup.in.credentials = creds; 149 150 session_setup.in.workgroup = ""; /* Only used with SPNEGO, which we are not doing */ 150 session_setup.in.gensec_settings = lp _gensec_settings(session, ctx->auth_ctx->lp_ctx);151 session_setup.in.gensec_settings = lpcfg_gensec_settings(session, ctx->auth_ctx->lp_ctx); 151 152 152 153 /* Check password with remove server - this should be async some day */ … … 157 158 } 158 159 159 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 160 NT_STATUS_HAVE_NO_MEMORY(server_info); 161 162 server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS); 163 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 164 165 /* is this correct? */ 166 server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS); 167 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 168 169 server_info->n_domain_groups = 0; 170 server_info->domain_groups = NULL; 160 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 161 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 162 163 user_info_dc->num_sids = 1; 164 165 /* This returns a pointer to a struct dom_sid, which is the 166 * same as a 1 element list of struct dom_sid */ 167 user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS); 168 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); 171 169 172 170 /* annoying, but the Anonymous really does have a session key, 173 171 and it is all zeros! */ 174 server_info->user_session_key = data_blob(NULL, 0); 175 server_info->lm_session_key = data_blob(NULL, 0); 176 177 server_info->account_name = talloc_strdup(server_info, user_info->client.account_name); 178 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 179 180 server_info->domain_name = talloc_strdup(server_info, user_info->client.domain_name); 181 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 182 183 server_info->full_name = NULL; 184 185 server_info->logon_script = talloc_strdup(server_info, ""); 186 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 187 188 server_info->profile_path = talloc_strdup(server_info, ""); 189 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 190 191 server_info->home_directory = talloc_strdup(server_info, ""); 192 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 193 194 server_info->home_drive = talloc_strdup(server_info, ""); 195 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 196 197 server_info->last_logon = 0; 198 server_info->last_logoff = 0; 199 server_info->acct_expiry = 0; 200 server_info->last_password_change = 0; 201 server_info->allow_password_change = 0; 202 server_info->force_password_change = 0; 203 204 server_info->logon_count = 0; 205 server_info->bad_password_count = 0; 206 207 server_info->acct_flags = ACB_NORMAL; 208 209 server_info->authenticated = false; 210 211 *_server_info = server_info; 172 user_info_dc->user_session_key = data_blob(NULL, 0); 173 user_info_dc->lm_session_key = data_blob(NULL, 0); 174 175 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 176 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 177 178 info->account_name = talloc_strdup(user_info_dc, user_info->client.account_name); 179 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 180 181 info->domain_name = talloc_strdup(user_info_dc, user_info->client.domain_name); 182 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 183 184 info->full_name = NULL; 185 186 info->logon_script = talloc_strdup(user_info_dc, ""); 187 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 188 189 info->profile_path = talloc_strdup(user_info_dc, ""); 190 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 191 192 info->home_directory = talloc_strdup(user_info_dc, ""); 193 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 194 195 info->home_drive = talloc_strdup(user_info_dc, ""); 196 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 197 198 info->last_logon = 0; 199 info->last_logoff = 0; 200 info->acct_expiry = 0; 201 info->last_password_change = 0; 202 info->allow_password_change = 0; 203 info->force_password_change = 0; 204 205 info->logon_count = 0; 206 info->bad_password_count = 0; 207 208 info->acct_flags = ACB_NORMAL; 209 210 info->authenticated = false; 211 212 *_user_info_dc = user_info_dc; 212 213 213 214 return nt_status; -
vendor/current/source4/auth/ntlm/auth_simple.c
r414 r740 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "lib/events/events.h"27 #include "param/param.h"28 #include "auth/session_proto.h"29 26 30 27 /* … … 39 36 const char *nt4_username, 40 37 const char *password, 38 const uint32_t logon_parameters, 41 39 struct auth_session_info **session_info) 42 40 { 43 41 struct auth_context *auth_context; 44 42 struct auth_usersupplied_info *user_info; 45 struct auth_ serversupplied_info *server_info;43 struct auth_user_info_dc *user_info_dc; 46 44 NTSTATUS nt_status; 47 45 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); … … 60 58 } 61 59 62 user_info = talloc (tmp_ctx, struct auth_usersupplied_info);60 user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info); 63 61 if (!user_info) { 64 62 talloc_free(tmp_ctx); … … 82 80 USER_INFO_DONT_CHECK_UNIX_ACCOUNT; 83 81 84 user_info->logon_parameters = 0; 82 user_info->logon_parameters = logon_parameters | 83 MSV1_0_CLEARTEXT_PASSWORD_ALLOWED | 84 MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED; 85 85 86 nt_status = auth_check_password(auth_context, tmp_ctx, user_info, & server_info);86 nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc); 87 87 if (!NT_STATUS_IS_OK(nt_status)) { 88 88 talloc_free(tmp_ctx); … … 91 91 92 92 if (session_info) { 93 nt_status = auth_generate_session_info(tmp_ctx, ev, lp_ctx, server_info, session_info); 93 uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS; 94 if (user_info_dc->info->authenticated) { 95 flags |= AUTH_SESSION_INFO_AUTHENTICATED; 96 } 97 nt_status = auth_context->generate_session_info(tmp_ctx, auth_context, 98 user_info_dc, 99 flags, 100 session_info); 94 101 95 102 if (NT_STATUS_IS_OK(nt_status)) { -
vendor/current/source4/auth/ntlm/auth_unix.c
r414 r740 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #include "system/passwd.h" /* needed by some systems for struct passwd */ 26 #include "lib/socket/socket.h" 27 #include "auth/ntlm/pam_errors.h" 26 #include "lib/socket/socket.h" 27 #include "lib/tsocket/tsocket.h" 28 #include "../libcli/auth/pam_errors.h" 28 29 #include "param/param.h" 29 30 … … 31 32 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set 32 33 */ 33 static NTSTATUS authunix_make_ server_info(TALLOC_CTX *mem_ctx,34 static NTSTATUS authunix_make_user_info_dc(TALLOC_CTX *mem_ctx, 34 35 const char *netbios_name, 35 36 const struct auth_usersupplied_info *user_info, 36 37 struct passwd *pwd, 37 struct auth_serversupplied_info **_server_info) 38 { 39 struct auth_serversupplied_info *server_info; 38 struct auth_user_info_dc **_user_info_dc) 39 { 40 struct auth_user_info_dc *user_info_dc; 41 struct auth_user_info *info; 40 42 NTSTATUS status; 41 43 42 44 /* This is a real, real hack */ 43 45 if (pwd->pw_uid == 0) { 44 status = auth_system_ server_info(mem_ctx, netbios_name, &server_info);46 status = auth_system_user_info_dc(mem_ctx, netbios_name, &user_info_dc); 45 47 if (!NT_STATUS_IS_OK(status)) { 46 48 return status; 47 49 } 48 50 49 server_info->account_name = talloc_steal(server_info, pwd->pw_name); 50 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 51 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 52 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 53 54 info->account_name = talloc_steal(info, pwd->pw_name); 55 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 51 56 52 server_info->domain_name = talloc_strdup(server_info, "unix");53 NT_STATUS_HAVE_NO_MEMORY( server_info->domain_name);57 info->domain_name = talloc_strdup(info, "unix"); 58 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 54 59 } else { 55 server_info = talloc(mem_ctx, struct auth_serversupplied_info);56 NT_STATUS_HAVE_NO_MEMORY( server_info);60 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 61 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 57 62 58 server_info->authenticated = true; 63 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 64 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 65 66 info->authenticated = true; 59 67 60 server_info->account_name = talloc_steal(server_info, pwd->pw_name);61 NT_STATUS_HAVE_NO_MEMORY( server_info->account_name);68 info->account_name = talloc_steal(info, pwd->pw_name); 69 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 62 70 63 server_info->domain_name = talloc_strdup(server_info, "unix");64 NT_STATUS_HAVE_NO_MEMORY( server_info->domain_name);71 info->domain_name = talloc_strdup(info, "unix"); 72 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 65 73 66 74 /* This isn't in any way correct.. */ 67 server_info->account_sid = NULL; 68 server_info->primary_group_sid = NULL; 69 server_info->n_domain_groups = 0; 70 server_info->domain_groups = NULL; 71 } 72 server_info->user_session_key = data_blob(NULL,0); 73 server_info->lm_session_key = data_blob(NULL,0); 74 75 server_info->full_name = talloc_steal(server_info, pwd->pw_gecos); 76 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 77 server_info->logon_script = talloc_strdup(server_info, ""); 78 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 79 server_info->profile_path = talloc_strdup(server_info, ""); 80 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 81 server_info->home_directory = talloc_strdup(server_info, ""); 82 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 83 server_info->home_drive = talloc_strdup(server_info, ""); 84 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 85 86 server_info->last_logon = 0; 87 server_info->last_logoff = 0; 88 server_info->acct_expiry = 0; 89 server_info->last_password_change = 0; 90 server_info->allow_password_change = 0; 91 server_info->force_password_change = 0; 92 server_info->logon_count = 0; 93 server_info->bad_password_count = 0; 94 server_info->acct_flags = 0; 95 96 *_server_info = server_info; 75 user_info_dc->num_sids = 0; 76 user_info_dc->sids = NULL; 77 } 78 user_info_dc->user_session_key = data_blob(NULL,0); 79 user_info_dc->lm_session_key = data_blob(NULL,0); 80 81 info->full_name = talloc_steal(info, pwd->pw_gecos); 82 NT_STATUS_HAVE_NO_MEMORY(info->full_name); 83 info->logon_script = talloc_strdup(info, ""); 84 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 85 info->profile_path = talloc_strdup(info, ""); 86 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 87 info->home_directory = talloc_strdup(info, ""); 88 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 89 info->home_drive = talloc_strdup(info, ""); 90 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 91 92 info->last_logon = 0; 93 info->last_logoff = 0; 94 info->acct_expiry = 0; 95 info->last_password_change = 0; 96 info->allow_password_change = 0; 97 info->force_password_change = 0; 98 info->logon_count = 0; 99 info->bad_password_count = 0; 100 info->acct_flags = 0; 101 102 *_user_info_dc = user_info_dc; 97 103 98 104 return NT_STATUS_OK; … … 430 436 } 431 437 432 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 438 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 433 439 const struct auth_usersupplied_info *user_info, struct passwd **pws) 434 440 { … … 459 465 */ 460 466 461 nt_status = smb_pam_start(&pamh, user_info->mapped.account_name, user_info->remote_host ? user_info->remote_host->addr : NULL, pamconv); 467 nt_status = smb_pam_start(&pamh, user_info->mapped.account_name, 468 user_info->remote_host ? tsocket_address_inet_addr_string(user_info->remote_host, ctx) : NULL, pamconv); 462 469 if (!NT_STATUS_IS_OK(nt_status)) { 463 470 return nt_status; 464 471 } 465 472 466 nt_status = smb_pam_auth(pamh, lp _null_passwords(lp_ctx), user_info->mapped.account_name);473 nt_status = smb_pam_auth(pamh, lpcfg_null_passwords(lp_ctx), user_info->mapped.account_name); 467 474 if (!NT_STATUS_IS_OK(nt_status)) { 468 475 smb_pam_end(pamh); … … 604 611 struct passwd *pws; 605 612 NTSTATUS nt_status; 606 int level = lp _passwordlevel(lp_ctx);613 int level = lpcfg_passwordlevel(lp_ctx); 607 614 608 615 *ret_passwd = NULL; … … 707 714 708 715 if (crypted[0] == '\0') { 709 if (!lp _null_passwords(lp_ctx)) {716 if (!lpcfg_null_passwords(lp_ctx)) { 710 717 DEBUG(2, ("Disallowing %s with null password\n", username)); 711 718 return NT_STATUS_LOGON_FAILURE; … … 792 799 TALLOC_CTX *mem_ctx, 793 800 const struct auth_usersupplied_info *user_info, 794 struct auth_ serversupplied_info **server_info)801 struct auth_user_info_dc **user_info_dc) 795 802 { 796 803 TALLOC_CTX *check_ctx; … … 813 820 } 814 821 815 nt_status = authunix_make_ server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),816 user_info, pwd, server_info);822 nt_status = authunix_make_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), 823 user_info, pwd, user_info_dc); 817 824 if (!NT_STATUS_IS_OK(nt_status)) { 818 825 talloc_free(check_ctx); -
vendor/current/source4/auth/ntlm/auth_util.c
r414 r740 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "auth/auth_proto.h"27 #include "libcli/security/security.h"28 26 #include "libcli/auth/libcli_auth.h" 29 #include "dsdb/samdb/samdb.h"30 #include "auth/credentials/credentials.h"31 27 #include "param/param.h" 32 28 … … 34 30 * which don't want to set a challenge 35 31 */ 36 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge)32 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 37 33 { 38 34 /* we don't want to set a challenge */ … … 79 75 } 80 76 81 *user_info_mapped = talloc (mem_ctx, struct auth_usersupplied_info);77 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 82 78 if (!*user_info_mapped) { 83 79 return NT_STATUS_NO_MEMORY; … … 127 123 case AUTH_PASSWORD_HASH: 128 124 { 129 const uint8_t *challenge;125 uint8_t chal[8]; 130 126 DATA_BLOB chall_blob; 131 user_info_temp = talloc (mem_ctx, struct auth_usersupplied_info);127 user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info); 132 128 if (!user_info_temp) { 133 129 return NT_STATUS_NO_MEMORY; … … 139 135 user_info_temp->mapped_state = to_state; 140 136 141 nt_status = auth_get_challenge(auth_context, &challenge);137 nt_status = auth_get_challenge(auth_context, chal); 142 138 if (!NT_STATUS_IS_OK(nt_status)) { 143 139 return nt_status; 144 140 } 145 141 146 chall_blob = data_blob_talloc(mem_ctx, chal lenge, 8);147 if (lp _client_ntlmv2_auth(auth_context->lp_ctx)) {148 DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx, lp _netbios_name(auth_context->lp_ctx), lp_workgroup(auth_context->lp_ctx));142 chall_blob = data_blob_talloc(mem_ctx, chal, 8); 143 if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) { 144 DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx, lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx)); 149 145 DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key; 150 146 … … 167 163 } else { 168 164 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); 169 SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal lenge, blob.data);165 SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data); 170 166 171 167 user_info_temp->password.response.nt = blob; 172 if (lp _client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {168 if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) { 173 169 DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24); 174 SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal lenge, blob.data);170 SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data); 175 171 user_info_temp->password.response.lanman = lm_blob; 176 172 } else { … … 195 191 struct samr_Password nt; 196 192 197 user_info_temp = talloc (mem_ctx, struct auth_usersupplied_info);193 user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info); 198 194 if (!user_info_temp) { 199 195 return NT_STATUS_NO_MEMORY; … … 236 232 return NT_STATUS_OK; 237 233 } 238 239 240 /**241 * Squash an NT_STATUS in line with security requirements.242 * In an attempt to avoid giving the whole game away when users243 * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and244 * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations245 * (session setups in particular).246 *247 * @param nt_status NTSTATUS input for squashing.248 * @return the 'squashed' nt_status249 **/250 _PUBLIC_ NTSTATUS auth_nt_status_squash(NTSTATUS nt_status)251 {252 if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {253 /* Match WinXP and don't give the game away */254 return NT_STATUS_LOGON_FAILURE;255 } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {256 /* Match WinXP and don't give the game away */257 return NT_STATUS_LOGON_FAILURE;258 }259 260 return nt_status;261 } -
vendor/current/source4/auth/ntlm/auth_winbind.c
r414 r740 26 26 #include "auth/ntlm/auth_proto.h" 27 27 #include "auth/auth_sam_reply.h" 28 #include "nsswitch/winbind_client.h" 29 #include "librpc/gen_ndr/ndr_netlogon.h" 30 #include "librpc/gen_ndr/ndr_winbind.h" 28 #include "librpc/gen_ndr/ndr_winbind_c.h" 31 29 #include "lib/messaging/irpc.h" 32 30 #include "param/param.h" 33 31 #include "nsswitch/libwbclient/wbclient.h" 34 #include "libcli/security/dom_sid.h" 35 36 static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, struct winbindd_response *response, struct netr_SamInfo3 *info3) 37 { 38 size_t len = response->length - sizeof(struct winbindd_response); 39 if (len > 4) { 40 enum ndr_err_code ndr_err; 41 DATA_BLOB blob; 42 blob.length = len - 4; 43 blob.data = (uint8_t *)(((char *)response->extra_data.data) + 4); 44 45 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, 46 iconv_convenience, info3, 47 (ndr_pull_flags_fn_t)ndr_pull_netr_SamInfo3); 48 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 49 return ndr_map_error2ntstatus(ndr_err); 50 } 51 52 return NT_STATUS_OK; 53 } else { 54 DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n")); 55 return NT_STATUS_UNSUCCESSFUL; 56 } 57 } 32 #include "libcli/security/security.h" 58 33 59 34 static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, 60 struct smb_iconv_convenience *ic,61 35 struct wbcAuthUserInfo *info, 62 36 struct netr_SamInfo3 *info3) … … 64 38 int i, j; 65 39 struct samr_RidWithAttribute *rids = NULL; 40 struct dom_sid *user_sid; 41 struct dom_sid *group_sid; 42 43 user_sid = (struct dom_sid *)(void *)&info->sids[0].sid; 44 group_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 66 45 67 46 info3->base.last_logon = info->logon_time; … … 103 82 } 104 83 105 dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[0].sid,84 dom_sid_split_rid(mem_ctx, user_sid, 106 85 &info3->base.domain_sid, 107 86 &info3->base.rid); 108 dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[1].sid, NULL,87 dom_sid_split_rid(mem_ctx, group_sid, NULL, 109 88 &info3->base.primary_gid); 110 89 … … 117 96 118 97 for (i = 2, j = 0; i < info->num_sids; ++i, ++j) { 98 struct dom_sid *tmp_sid; 99 tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid; 100 119 101 rids[j].attributes = info->sids[i].attributes; 120 dom_sid_split_rid(mem_ctx, 121 (struct dom_sid2 *) &info->sids[i].sid, 102 dom_sid_split_rid(mem_ctx, tmp_sid, 122 103 NULL, &rids[j].rid); 123 104 } … … 138 119 /* TODO: maybe limit the user scope to remote users only */ 139 120 return NT_STATUS_OK; 140 }141 142 /*143 Authenticate a user with a challenge/response144 using the samba3 winbind protocol145 */146 static NTSTATUS winbind_check_password_samba3(struct auth_method_context *ctx,147 TALLOC_CTX *mem_ctx,148 const struct auth_usersupplied_info *user_info,149 struct auth_serversupplied_info **server_info)150 {151 struct winbindd_request request;152 struct winbindd_response response;153 NSS_STATUS result;154 NTSTATUS nt_status;155 struct netr_SamInfo3 info3;156 157 /* Send off request */158 const struct auth_usersupplied_info *user_info_temp;159 nt_status = encrypt_user_info(mem_ctx, ctx->auth_ctx,160 AUTH_PASSWORD_RESPONSE,161 user_info, &user_info_temp);162 if (!NT_STATUS_IS_OK(nt_status)) {163 return nt_status;164 }165 user_info = user_info_temp;166 167 ZERO_STRUCT(request);168 ZERO_STRUCT(response);169 request.flags = WBFLAG_PAM_INFO3_NDR;170 171 request.data.auth_crap.logon_parameters = user_info->logon_parameters;172 173 safe_strcpy(request.data.auth_crap.user,174 user_info->client.account_name, sizeof(fstring));175 safe_strcpy(request.data.auth_crap.domain,176 user_info->client.domain_name, sizeof(fstring));177 safe_strcpy(request.data.auth_crap.workstation,178 user_info->workstation_name, sizeof(fstring));179 180 memcpy(request.data.auth_crap.chal, ctx->auth_ctx->challenge.data.data, sizeof(request.data.auth_crap.chal));181 182 request.data.auth_crap.lm_resp_len = MIN(user_info->password.response.lanman.length,183 sizeof(request.data.auth_crap.lm_resp));184 request.data.auth_crap.nt_resp_len = MIN(user_info->password.response.nt.length,185 sizeof(request.data.auth_crap.nt_resp));186 187 memcpy(request.data.auth_crap.lm_resp, user_info->password.response.lanman.data,188 request.data.auth_crap.lm_resp_len);189 memcpy(request.data.auth_crap.nt_resp, user_info->password.response.nt.data,190 request.data.auth_crap.nt_resp_len);191 192 result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);193 194 nt_status = NT_STATUS(response.data.auth.nt_status);195 NT_STATUS_NOT_OK_RETURN(nt_status);196 197 if (result == NSS_STATUS_SUCCESS && response.extra_data.data) {198 union netr_Validation validation;199 200 nt_status = get_info3_from_ndr(mem_ctx, lp_iconv_convenience(ctx->auth_ctx->lp_ctx), &response, &info3);201 SAFE_FREE(response.extra_data.data);202 NT_STATUS_NOT_OK_RETURN(nt_status);203 204 validation.sam3 = &info3;205 nt_status = make_server_info_netlogon_validation(mem_ctx,206 user_info->client.account_name,207 3, &validation,208 server_info);209 return nt_status;210 } else if (result == NSS_STATUS_SUCCESS && !response.extra_data.data) {211 DEBUG(0, ("Winbindd authenticated the user [%s]\\[%s], "212 "but did not include the required info3 reply!\n",213 user_info->client.domain_name, user_info->client.account_name));214 return NT_STATUS_INSUFFICIENT_LOGON_INFO;215 } else if (NT_STATUS_IS_OK(nt_status)) {216 DEBUG(1, ("Winbindd authentication for [%s]\\[%s] failed, "217 "but no error code is available!\n",218 user_info->client.domain_name, user_info->client.account_name));219 return NT_STATUS_NO_LOGON_SERVERS;220 }221 222 return nt_status;223 121 } 224 122 … … 234 132 TALLOC_CTX *mem_ctx, 235 133 const struct auth_usersupplied_info *user_info, 236 struct auth_ serversupplied_info **server_info)134 struct auth_user_info_dc **user_info_dc) 237 135 { 238 136 NTSTATUS status; 239 struct server_id *winbind_servers;137 struct dcerpc_binding_handle *irpc_handle; 240 138 struct winbind_check_password_state *s; 241 139 const struct auth_usersupplied_info *user_info_new; 242 140 struct netr_IdentityInfo *identity_info; 243 141 142 if (!ctx->auth_ctx->msg_ctx) { 143 DEBUG(0,("winbind_check_password: auth_context_create was called with out messaging context\n")); 144 return NT_STATUS_INTERNAL_ERROR; 145 } 146 244 147 s = talloc(mem_ctx, struct winbind_check_password_state); 245 148 NT_STATUS_HAVE_NO_MEMORY(s); 246 149 247 winbind_servers = irpc_servers_byname(ctx->auth_ctx->msg_ctx, s, "winbind_server"); 248 if ((winbind_servers == NULL) || (winbind_servers[0].id == 0)) { 150 irpc_handle = irpc_binding_handle_by_name(s, ctx->auth_ctx->msg_ctx, 151 "winbind_server", 152 &ndr_table_winbind); 153 if (irpc_handle == NULL) { 249 154 DEBUG(0, ("Winbind authentication for [%s]\\[%s] failed, " 250 155 "no winbind_server running!\n", … … 272 177 } else { 273 178 struct netr_NetworkInfo *network_info; 274 const uint8_t *challenge;179 uint8_t chal[8]; 275 180 276 181 status = encrypt_user_info(s, ctx->auth_ctx, AUTH_PASSWORD_RESPONSE, … … 282 187 NT_STATUS_HAVE_NO_MEMORY(network_info); 283 188 284 status = auth_get_challenge(ctx->auth_ctx, &challenge);189 status = auth_get_challenge(ctx->auth_ctx, chal); 285 190 NT_STATUS_NOT_OK_RETURN(status); 286 191 287 memcpy(network_info->challenge, chal lenge, sizeof(network_info->challenge));192 memcpy(network_info->challenge, chal, sizeof(network_info->challenge)); 288 193 289 194 network_info->nt.length = user_info->password.response.nt.length; … … 307 212 s->req.in.validation_level = 3; 308 213 309 status = IRPC_CALL(ctx->auth_ctx->msg_ctx, winbind_servers[0], 310 winbind, WINBIND_SAMLOGON, 311 &s->req, s); 214 status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req); 312 215 NT_STATUS_NOT_OK_RETURN(status); 313 216 314 status = make_ server_info_netlogon_validation(mem_ctx,217 status = make_user_info_dc_netlogon_validation(mem_ctx, 315 218 user_info->client.account_name, 316 219 s->req.in.validation_level, 317 220 &s->req.out.validation, 318 server_info);221 user_info_dc); 319 222 NT_STATUS_NOT_OK_RETURN(status); 320 223 … … 329 232 TALLOC_CTX *mem_ctx, 330 233 const struct auth_usersupplied_info *user_info, 331 struct auth_ serversupplied_info **server_info)234 struct auth_user_info_dc **user_info_dc) 332 235 { 333 236 struct wbcAuthUserParams params; … … 382 285 383 286 wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); 384 if ( !WBC_ERROR_IS_OK(wbc_status)) {287 if (wbc_status == WBC_ERR_AUTH_ERROR) { 385 288 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 386 289 err->nt_string, err->nt_status, err->display_string)); … … 389 292 wbcFreeMemory(err); 390 293 NT_STATUS_NOT_OK_RETURN(nt_status); 391 } 392 nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, 393 lp_iconv_convenience(ctx->auth_ctx->lp_ctx), 394 info, &info3); 294 } else if (!WBC_ERROR_IS_OK(wbc_status)) { 295 DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n", 296 wbc_status, wbcErrorString(wbc_status))); 297 return NT_STATUS_LOGON_FAILURE; 298 } 299 nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3); 395 300 wbcFreeMemory(info); 396 301 NT_STATUS_NOT_OK_RETURN(nt_status); 397 302 398 303 validation.sam3 = &info3; 399 nt_status = make_ server_info_netlogon_validation(mem_ctx,304 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 400 305 user_info->client.account_name, 401 3, &validation, server_info);306 3, &validation, user_info_dc); 402 307 return nt_status; 403 308 404 309 } 405 406 static const struct auth_operations winbind_samba3_ops = {407 .name = "winbind_samba3",408 .get_challenge = auth_get_challenge_not_implemented,409 .want_check = winbind_want_check,410 .check_password = winbind_check_password_samba3411 };412 310 413 311 static const struct auth_operations winbind_ops = { … … 429 327 NTSTATUS ret; 430 328 431 ret = auth_register(&winbind_samba3_ops);432 if (!NT_STATUS_IS_OK(ret)) {433 DEBUG(0,("Failed to register 'winbind_samba3' auth backend!\n"));434 return ret;435 }436 437 329 ret = auth_register(&winbind_ops); 438 330 if (!NT_STATUS_IS_OK(ret)) { -
vendor/current/source4/auth/ntlmssp/ntlmssp.c
r414 r740 24 24 #include "includes.h" 25 25 #include "auth/ntlmssp/ntlmssp.h" 26 #include "../librpc/gen_ndr/ntlmssp.h"27 26 #include "../libcli/auth/libcli_auth.h" 28 27 #include "librpc/gen_ndr/ndr_dcerpc.h" 29 #include "auth/credentials/credentials.h"30 28 #include "auth/gensec/gensec.h" 31 29 #include "auth/gensec/gensec_proto.h" 32 #include "param/param.h"33 30 34 31 /** … … 51 48 .role = NTLMSSP_SERVER, 52 49 .command = NTLMSSP_NEGOTIATE, 53 .sync_fn = ntlmssp_server_negotiate,50 .sync_fn = gensec_ntlmssp_server_negotiate, 54 51 },{ 55 52 .role = NTLMSSP_CLIENT, … … 59 56 .role = NTLMSSP_SERVER, 60 57 .command = NTLMSSP_AUTH, 61 .sync_fn = ntlmssp_server_auth,58 .sync_fn = gensec_ntlmssp_server_auth, 62 59 } 63 60 }; 64 61 65 66 /**67 * Print out the NTLMSSP flags for debugging68 * @param neg_flags The flags from the packet69 */70 71 void debug_ntlmssp_flags(uint32_t neg_flags)72 {73 DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));74 75 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)76 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n"));77 if (neg_flags & NTLMSSP_NEGOTIATE_OEM)78 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n"));79 if (neg_flags & NTLMSSP_REQUEST_TARGET)80 DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n"));81 if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)82 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n"));83 if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)84 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n"));85 if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)86 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM\n"));87 if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)88 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n"));89 if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)90 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n"));91 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)92 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n"));93 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)94 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));95 if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)96 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));97 if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)98 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));99 if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)100 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));101 if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)102 DEBUGADD(4, (" NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));103 if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)104 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n"));105 if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)106 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_TARGET_INFO\n"));107 if (neg_flags & NTLMSSP_NEGOTIATE_128)108 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n"));109 if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)110 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n"));111 if (neg_flags & NTLMSSP_NEGOTIATE_56)112 DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n"));113 }114 62 115 63 static NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security, … … 123 71 } 124 72 125 static NTSTATUS gensec_ntlmssp_update_find(struct gensec_ntlmssp_state *gensec_ntlmssp_state,73 static NTSTATUS gensec_ntlmssp_update_find(struct ntlmssp_state *ntlmssp_state, 126 74 const DATA_BLOB input, uint32_t *idx) 127 75 { 128 struct gensec_security *gensec_security = gensec_ntlmssp_state->gensec_security; 76 struct gensec_ntlmssp_context *gensec_ntlmssp = 77 talloc_get_type_abort(ntlmssp_state->callback_private, 78 struct gensec_ntlmssp_context); 79 struct gensec_security *gensec_security = gensec_ntlmssp->gensec_security; 129 80 uint32_t ntlmssp_command; 130 81 uint32_t i; 131 82 132 if ( gensec_ntlmssp_state->expected_state == NTLMSSP_DONE) {83 if (ntlmssp_state->expected_state == NTLMSSP_DONE) { 133 84 /* We are strict here because other modules, which we 134 85 * don't fully control (such as GSSAPI) are also … … 140 91 141 92 if (!input.length) { 142 switch ( gensec_ntlmssp_state->role) {93 switch (ntlmssp_state->role) { 143 94 case NTLMSSP_CLIENT: 144 95 ntlmssp_command = NTLMSSP_INITIAL; … … 156 107 } 157 108 } else { 158 if (!msrpc_parse( gensec_ntlmssp_state,109 if (!msrpc_parse(ntlmssp_state, 159 110 &input, "Cd", 160 111 "NTLMSSP", … … 166 117 } 167 118 168 if (ntlmssp_command != gensec_ntlmssp_state->expected_state) {169 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, gensec_ntlmssp_state->expected_state));119 if (ntlmssp_command != ntlmssp_state->expected_state) { 120 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); 170 121 return NT_STATUS_INVALID_PARAMETER; 171 122 } 172 123 173 124 for (i=0; i < ARRAY_SIZE(ntlmssp_callbacks); i++) { 174 if (ntlmssp_callbacks[i].role == gensec_ntlmssp_state->role &&125 if (ntlmssp_callbacks[i].role == ntlmssp_state->role && 175 126 ntlmssp_callbacks[i].command == ntlmssp_command) { 176 127 *idx = i; … … 180 131 181 132 DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 182 gensec_ntlmssp_state->role, ntlmssp_command));133 ntlmssp_state->role, ntlmssp_command)); 183 134 184 135 return NT_STATUS_INVALID_PARAMETER; … … 200 151 const DATA_BLOB input, DATA_BLOB *out) 201 152 { 202 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 153 struct gensec_ntlmssp_context *gensec_ntlmssp = 154 talloc_get_type_abort(gensec_security->private_data, 155 struct gensec_ntlmssp_context); 156 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 203 157 NTSTATUS status; 204 158 uint32_t i; … … 209 163 /* if the caller doesn't want to manage/own the memory, 210 164 we can put it on our context */ 211 out_mem_ctx = gensec_ntlmssp_state;212 } 213 214 status = gensec_ntlmssp_update_find( gensec_ntlmssp_state, input, &i);165 out_mem_ctx = ntlmssp_state; 166 } 167 168 status = gensec_ntlmssp_update_find(ntlmssp_state, input, &i); 215 169 NT_STATUS_NOT_OK_RETURN(status); 216 170 … … 224 178 * Return the NTLMSSP master session key 225 179 * 226 * @param gensec_ntlmssp_state NTLMSSP State180 * @param ntlmssp_state NTLMSSP State 227 181 */ 228 182 … … 230 184 DATA_BLOB *session_key) 231 185 { 232 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 233 234 if (gensec_ntlmssp_state->expected_state != NTLMSSP_DONE) { 186 struct gensec_ntlmssp_context *gensec_ntlmssp = 187 talloc_get_type_abort(gensec_security->private_data, 188 struct gensec_ntlmssp_context); 189 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 190 191 if (ntlmssp_state->expected_state != NTLMSSP_DONE) { 235 192 return NT_STATUS_NO_USER_SESSION_KEY; 236 193 } 237 194 238 if (! gensec_ntlmssp_state->session_key.data) {195 if (!ntlmssp_state->session_key.data) { 239 196 return NT_STATUS_NO_USER_SESSION_KEY; 240 197 } 241 *session_key = gensec_ntlmssp_state->session_key;198 *session_key = ntlmssp_state->session_key; 242 199 243 200 return NT_STATUS_OK; 244 }245 246 void ntlmssp_handle_neg_flags(struct gensec_ntlmssp_state *gensec_ntlmssp_state,247 uint32_t neg_flags, bool allow_lm)248 {249 if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {250 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;251 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;252 gensec_ntlmssp_state->unicode = true;253 } else {254 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;255 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;256 gensec_ntlmssp_state->unicode = false;257 }258 259 if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !gensec_ntlmssp_state->use_ntlmv2) {260 /* other end forcing us to use LM */261 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;262 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;263 } else {264 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;265 }266 267 if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {268 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;269 }270 271 if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {272 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;273 }274 275 if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {276 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;277 }278 279 if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {280 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;281 }282 283 if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {284 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;285 }286 287 if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {288 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;289 }290 291 if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {292 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;293 }294 295 /* Woop Woop - unknown flag for Windows compatibility...296 What does this really do ? JRA. */297 if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {298 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;299 }300 301 if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {302 gensec_ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;303 }304 305 }306 307 /**308 Weaken NTLMSSP keys to cope with down-level clients and servers.309 310 We probably should have some parameters to control this, but as311 it only occours for LM_KEY connections, and this is controlled312 by the client lanman auth/lanman auth parameters, it isn't too bad.313 */314 315 DATA_BLOB ntlmssp_weakend_key(struct gensec_ntlmssp_state *gensec_ntlmssp_state,316 TALLOC_CTX *mem_ctx)317 {318 DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,319 gensec_ntlmssp_state->session_key.data,320 gensec_ntlmssp_state->session_key.length);321 /* Nothing to weaken. We certainly don't want to 'extend' the length... */322 if (weakened_key.length < 16) {323 /* perhaps there was no key? */324 return weakened_key;325 }326 327 /* Key weakening not performed on the master key for NTLM2328 and does not occour for NTLM1. Therefore we only need329 to do this for the LM_KEY.330 */331 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {332 /* LM key doesn't support 128 bit crypto, so this is333 * the best we can do. If you negotiate 128 bit, but334 * not 56, you end up with 40 bit... */335 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {336 weakened_key.data[7] = 0xa0;337 weakened_key.length = 8;338 } else { /* forty bits */339 weakened_key.data[5] = 0xe5;340 weakened_key.data[6] = 0x38;341 weakened_key.data[7] = 0xb0;342 weakened_key.length = 8;343 }344 }345 return weakened_key;346 201 } 347 202 … … 349 204 uint32_t feature) 350 205 { 351 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 206 struct gensec_ntlmssp_context *gensec_ntlmssp = 207 talloc_get_type_abort(gensec_security->private_data, 208 struct gensec_ntlmssp_context); 209 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 210 352 211 if (feature & GENSEC_FEATURE_SIGN) { 353 if (! gensec_ntlmssp_state->session_key.length) {212 if (!ntlmssp_state->session_key.length) { 354 213 return false; 355 214 } 356 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {215 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { 357 216 return true; 358 217 } 359 218 } 360 219 if (feature & GENSEC_FEATURE_SEAL) { 361 if (! gensec_ntlmssp_state->session_key.length) {220 if (!ntlmssp_state->session_key.length) { 362 221 return false; 363 222 } 364 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {223 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { 365 224 return true; 366 225 } 367 226 } 368 227 if (feature & GENSEC_FEATURE_SESSION_KEY) { 369 if ( gensec_ntlmssp_state->session_key.length) {228 if (ntlmssp_state->session_key.length) { 370 229 return true; 371 230 } … … 375 234 } 376 235 if (feature & GENSEC_FEATURE_ASYNC_REPLIES) { 377 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {236 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 378 237 return true; 379 238 } … … 384 243 NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security) 385 244 { 386 struct gensec_ntlmssp_state *gensec_ntlmssp_state; 387 388 gensec_ntlmssp_state = talloc_zero(gensec_security, struct gensec_ntlmssp_state); 389 if (!gensec_ntlmssp_state) { 245 struct gensec_ntlmssp_context *gensec_ntlmssp; 246 struct ntlmssp_state *ntlmssp_state; 247 248 gensec_ntlmssp = talloc_zero(gensec_security, 249 struct gensec_ntlmssp_context); 250 if (!gensec_ntlmssp) { 390 251 return NT_STATUS_NO_MEMORY; 391 252 } 392 253 393 gensec_ntlmssp_state->gensec_security = gensec_security; 394 gensec_ntlmssp_state->auth_context = NULL; 395 gensec_ntlmssp_state->server_info = NULL; 396 397 gensec_security->private_data = gensec_ntlmssp_state; 254 gensec_ntlmssp->gensec_security = gensec_security; 255 256 ntlmssp_state = talloc_zero(gensec_ntlmssp, 257 struct ntlmssp_state); 258 if (!ntlmssp_state) { 259 return NT_STATUS_NO_MEMORY; 260 } 261 262 ntlmssp_state->callback_private = gensec_ntlmssp; 263 264 gensec_ntlmssp->ntlmssp_state = ntlmssp_state; 265 266 gensec_security->private_data = gensec_ntlmssp; 398 267 return NT_STATUS_OK; 399 268 } … … 406 275 static const struct gensec_security_ops gensec_ntlmssp_security_ops = { 407 276 .name = "ntlmssp", 408 .sasl_name = "NTLM",277 .sasl_name = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */ 409 278 .auth_type = DCERPC_AUTH_TYPE_NTLMSSP, 410 279 .oid = gensec_ntlmssp_oids, -
vendor/current/source4/auth/ntlmssp/ntlmssp.h
r414 r740 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 SMB parameters and setup … … 5 5 Copyright (C) Luke Kenneth Casson Leighton 1996-1997 6 6 Copyright (C) Paul Ashton 1997 7 7 Copyright (C) Andrew Bartlett 2010 8 8 9 This program is free software; you can redistribute it and/or modify 9 10 it under the terms of the GNU General Public License as published by 10 11 the Free Software Foundation; either version 3 of the License, or 11 12 (at your option) any later version. 12 13 13 14 This program is distributed in the hope that it will be useful, 14 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 17 GNU General Public License for more details. 17 18 18 19 You should have received a copy of the GNU General Public License 19 20 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 21 */ 21 22 22 #include "librpc/gen_ndr/samr.h"23 23 #include "../librpc/gen_ndr/ntlmssp.h" 24 #include "../libcli/auth/ntlmssp.h" 24 25 25 /* NTLMSSP mode */ 26 enum ntlmssp_role 27 { 28 NTLMSSP_SERVER, 29 NTLMSSP_CLIENT 30 }; 31 32 /* NTLMSSP message types */ 33 enum ntlmssp_message_type 34 { 35 NTLMSSP_INITIAL = 0 /* samba internal state */, 36 NTLMSSP_NEGOTIATE = 1, 37 NTLMSSP_CHALLENGE = 2, 38 NTLMSSP_AUTH = 3, 39 NTLMSSP_UNKNOWN = 4, 40 NTLMSSP_DONE = 5 /* samba final state */ 41 }; 42 43 struct gensec_ntlmssp_state 44 { 26 struct gensec_ntlmssp_context { 45 27 struct gensec_security *gensec_security; 46 47 enum ntlmssp_role role; 48 enum samr_Role server_role; 49 uint32_t expected_state; 50 51 bool unicode; 52 bool use_ntlmv2; 53 bool use_nt_response; /* Set to 'False' to debug what happens when the NT response is omited */ 54 bool allow_lm_key; /* The LM_KEY code is not functional at this point, and it's not 55 very secure anyway */ 56 57 bool server_multiple_authentications; /* Set to 'True' to allow squid 2.5 58 style 'challenge caching' */ 59 60 char *user; 61 const char *domain; 62 const char *workstation; 63 char *server_domain; 64 65 DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */ 66 67 DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */ 68 DATA_BLOB lm_resp; 69 DATA_BLOB nt_resp; 70 DATA_BLOB session_key; 71 72 uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */ 73 74 /* internal variables used by KEY_EXCH (client-supplied user session key */ 75 DATA_BLOB encrypted_session_key; 76 77 /** 78 * Callback to get the 'challenge' used for NTLM authentication. 79 * 80 * @param ntlmssp_state This structure 81 * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication 82 * 83 */ 84 const uint8_t *(*get_challenge)(const struct gensec_ntlmssp_state *); 85 86 /** 87 * Callback to find if the challenge used by NTLM authentication may be modified 88 * 89 * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the 90 * current 'security=server' implementation.. 91 * 92 * @param ntlmssp_state This structure 93 * @return Can the challenge be set to arbitary values? 94 * 95 */ 96 bool (*may_set_challenge)(const struct gensec_ntlmssp_state *); 97 98 /** 99 * Callback to set the 'challenge' used for NTLM authentication. 100 * 101 * The callback may use the void *auth_context to store state information, but the same value is always available 102 * from the DATA_BLOB chal on this structure. 103 * 104 * @param ntlmssp_state This structure 105 * @param challenge 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication 106 * 107 */ 108 NTSTATUS (*set_challenge)(struct gensec_ntlmssp_state *, DATA_BLOB *challenge); 109 110 /** 111 * Callback to check the user's password. 112 * 113 * The callback must reads the feilds of this structure for the information it needs on the user 114 * @param ntlmssp_state This structure 115 * @param nt_session_key If an NT session key is returned by the authentication process, return it here 116 * @param lm_session_key If an LM session key is returned by the authentication process, return it here 117 * 118 */ 119 NTSTATUS (*check_password)(struct gensec_ntlmssp_state *, 120 TALLOC_CTX *mem_ctx, 121 DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key); 122 123 const char *server_name; 124 125 bool doing_ntlm2; 126 127 union { 128 /* NTLM */ 129 struct { 130 uint32_t seq_num; 131 struct arcfour_state *arcfour_state; 132 } ntlm; 133 134 /* NTLM2 */ 135 struct { 136 uint32_t send_seq_num; 137 uint32_t recv_seq_num; 138 DATA_BLOB send_sign_key; 139 DATA_BLOB recv_sign_key; 140 struct arcfour_state *send_seal_arcfour_state; 141 struct arcfour_state *recv_seal_arcfour_state; 142 143 /* internal variables used by NTLM2 */ 144 uint8_t session_nonce[16]; 145 } ntlm2; 146 } crypt; 147 28 struct ntlmssp_state *ntlmssp_state; 148 29 struct auth_context *auth_context; 149 struct auth_ serversupplied_info *server_info;30 struct auth_user_info_dc *user_info_dc; 150 31 }; 151 32 … … 153 34 struct auth_session_info; 154 35 36 NTSTATUS gensec_ntlmssp_init(void); 37 155 38 #include "auth/ntlmssp/proto.h" -
vendor/current/source4/auth/ntlmssp/ntlmssp_client.c
r414 r740 24 24 #include "includes.h" 25 25 #include "auth/ntlmssp/ntlmssp.h" 26 #include "../librpc/gen_ndr/ntlmssp.h"27 26 #include "../lib/crypto/crypto.h" 28 27 #include "../libcli/auth/libcli_auth.h" … … 30 29 #include "auth/gensec/gensec.h" 31 30 #include "param/param.h" 31 #include "libcli/auth/ntlmssp_private.h" 32 32 33 33 /********************************************************************* … … 49 49 DATA_BLOB in, DATA_BLOB *out) 50 50 { 51 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 52 const char *domain = gensec_ntlmssp_state->domain; 51 struct gensec_ntlmssp_context *gensec_ntlmssp = 52 talloc_get_type_abort(gensec_security->private_data, 53 struct gensec_ntlmssp_context); 54 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 55 const char *domain = ntlmssp_state->domain; 53 56 const char *workstation = cli_credentials_get_workstation(gensec_security->credentials); 57 NTSTATUS status; 54 58 55 59 /* These don't really matter in the initial packet, so don't panic if they are not set */ … … 62 66 } 63 67 64 if ( gensec_ntlmssp_state->unicode) {65 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;68 if (ntlmssp_state->unicode) { 69 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; 66 70 } else { 67 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;71 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; 68 72 } 69 73 70 if ( gensec_ntlmssp_state->use_ntlmv2) {71 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;74 if (ntlmssp_state->use_ntlmv2) { 75 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 72 76 } 73 77 74 78 /* generate the ntlmssp negotiate packet */ 75 msrpc_gen(out_mem_ctx,79 status = msrpc_gen(out_mem_ctx, 76 80 out, "CddAA", 77 81 "NTLMSSP", 78 82 NTLMSSP_NEGOTIATE, 79 gensec_ntlmssp_state->neg_flags,83 ntlmssp_state->neg_flags, 80 84 domain, 81 85 workstation); 82 86 83 gensec_ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; 87 if (!NT_STATUS_IS_OK(status)) { 88 return status; 89 } 90 91 ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; 84 92 85 93 return NT_STATUS_MORE_PROCESSING_REQUIRED; … … 100 108 const DATA_BLOB in, DATA_BLOB *out) 101 109 { 102 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 110 struct gensec_ntlmssp_context *gensec_ntlmssp = 111 talloc_get_type_abort(gensec_security->private_data, 112 struct gensec_ntlmssp_context); 113 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 103 114 uint32_t chal_flags, ntlmssp_command, unkn1, unkn2; 104 115 DATA_BLOB server_domain_blob; … … 140 151 debug_ntlmssp_flags(chal_flags); 141 152 142 ntlmssp_handle_neg_flags( gensec_ntlmssp_state, chal_flags, gensec_ntlmssp_state->allow_lm_key);143 144 if ( gensec_ntlmssp_state->unicode) {153 ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key); 154 155 if (ntlmssp_state->unicode) { 145 156 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { 146 157 chal_parse_string = "CdUdbddB"; … … 174 185 } 175 186 176 gensec_ntlmssp_state->server_domain = server_domain; 187 if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) { 188 ntlmssp_state->server.is_standalone = true; 189 } else { 190 ntlmssp_state->server.is_standalone = false; 191 } 192 /* TODO: parse struct_blob and fill in the rest */ 193 ntlmssp_state->server.netbios_name = ""; 194 ntlmssp_state->server.netbios_domain = server_domain; 195 ntlmssp_state->server.dns_name = ""; 196 ntlmssp_state->server.dns_domain = ""; 177 197 178 198 if (challenge_blob.length != 8) { … … 184 204 &user, &domain); 185 205 186 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {206 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 187 207 flags |= CLI_CRED_NTLM2; 188 208 } 189 if ( gensec_ntlmssp_state->use_ntlmv2) {209 if (ntlmssp_state->use_ntlmv2) { 190 210 flags |= CLI_CRED_NTLMv2_AUTH; 191 211 } 192 if ( gensec_ntlmssp_state->use_nt_response) {212 if (ntlmssp_state->use_nt_response) { 193 213 flags |= CLI_CRED_NTLM_AUTH; 194 214 } 195 if (lp _client_lanman_auth(gensec_security->settings->lp_ctx)) {215 if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) { 196 216 flags |= CLI_CRED_LANMAN_AUTH; 197 217 } … … 209 229 /* LM Key is still possible, just silly. Fortunetly 210 230 * we require command line options to end up here */ 211 /* gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */231 /* ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */ 212 232 } 213 233 214 234 if (!(flags & CLI_CRED_NTLM2)) { 215 235 /* NTLM2 is incompatible... */ 216 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;236 ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; 217 237 } 218 238 219 if (( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)220 && lp _client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) {239 if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 240 && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { 221 241 DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); 222 242 if (lm_response.length == 24) { … … 235 255 /* Key exchange encryptes a new client-generated session key with 236 256 the password-derived key */ 237 if ( gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {257 if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { 238 258 /* Make up a new session key */ 239 259 uint8_t client_session_key[16]; … … 241 261 242 262 /* Encrypt the new session key with the old one */ 243 encrypted_session_key = data_blob_talloc( gensec_ntlmssp_state,263 encrypted_session_key = data_blob_talloc(ntlmssp_state, 244 264 client_session_key, sizeof(client_session_key)); 245 265 dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); … … 252 272 253 273 DEBUG(3, ("NTLMSSP: Set final flags:\n")); 254 debug_ntlmssp_flags( gensec_ntlmssp_state->neg_flags);274 debug_ntlmssp_flags(ntlmssp_state->neg_flags); 255 275 256 276 /* this generates the actual auth packet */ 257 if (!msrpc_gen(mem_ctx,277 nt_status = msrpc_gen(mem_ctx, 258 278 out, auth_gen_string, 259 279 "NTLMSSP", … … 265 285 cli_credentials_get_workstation(gensec_security->credentials), 266 286 encrypted_session_key.data, encrypted_session_key.length, 267 gensec_ntlmssp_state->neg_flags)) { 287 ntlmssp_state->neg_flags); 288 if (!NT_STATUS_IS_OK(nt_status)) { 268 289 talloc_free(mem_ctx); 269 return NT_STATUS_NO_MEMORY;270 } 271 272 gensec_ntlmssp_state->session_key = session_key;273 talloc_steal( gensec_ntlmssp_state, session_key.data);290 return nt_status; 291 } 292 293 ntlmssp_state->session_key = session_key; 294 talloc_steal(ntlmssp_state, session_key.data); 274 295 275 296 talloc_steal(out_mem_ctx, out->data); 276 297 277 gensec_ntlmssp_state->chal = challenge_blob;278 gensec_ntlmssp_state->lm_resp = lm_response;279 talloc_steal( gensec_ntlmssp_state->lm_resp.data, lm_response.data);280 gensec_ntlmssp_state->nt_resp = nt_response;281 talloc_steal( gensec_ntlmssp_state->nt_resp.data, nt_response.data);282 283 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;298 ntlmssp_state->chal = challenge_blob; 299 ntlmssp_state->lm_resp = lm_response; 300 talloc_steal(ntlmssp_state->lm_resp.data, lm_response.data); 301 ntlmssp_state->nt_resp = nt_response; 302 talloc_steal(ntlmssp_state->nt_resp.data, nt_response.data); 303 304 ntlmssp_state->expected_state = NTLMSSP_DONE; 284 305 285 306 if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) { 286 nt_status = ntlmssp_sign_init( gensec_ntlmssp_state);307 nt_status = ntlmssp_sign_init(ntlmssp_state); 287 308 if (!NT_STATUS_IS_OK(nt_status)) { 288 309 DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", … … 299 320 NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) 300 321 { 301 struct gensec_ntlmssp_state *gensec_ntlmssp_state; 322 struct gensec_ntlmssp_context *gensec_ntlmssp; 323 struct ntlmssp_state *ntlmssp_state; 302 324 NTSTATUS nt_status; 303 325 … … 305 327 NT_STATUS_NOT_OK_RETURN(nt_status); 306 328 307 gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 308 309 gensec_ntlmssp_state->role = NTLMSSP_CLIENT; 310 311 gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx); 312 313 gensec_ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true); 314 315 gensec_ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); 316 317 gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->settings->lp_ctx) 329 gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, 330 struct gensec_ntlmssp_context); 331 ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 332 333 ntlmssp_state->role = NTLMSSP_CLIENT; 334 335 ntlmssp_state->domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); 336 337 ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true); 338 339 ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); 340 341 ntlmssp_state->allow_lm_key = (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) 318 342 && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false) 319 343 || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false))); 320 344 321 gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->settings->lp_ctx);322 323 gensec_ntlmssp_state->expected_state = NTLMSSP_INITIAL;324 325 gensec_ntlmssp_state->neg_flags =345 ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx); 346 347 ntlmssp_state->expected_state = NTLMSSP_INITIAL; 348 349 ntlmssp_state->neg_flags = 326 350 NTLMSSP_NEGOTIATE_NTLM | 327 351 NTLMSSP_REQUEST_TARGET; 328 352 329 353 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) { 330 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;354 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; 331 355 } 332 356 333 357 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) { 334 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;358 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; 335 359 } 336 360 337 361 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) { 338 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;362 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; 339 363 } 340 364 341 365 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) { 342 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;366 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; 343 367 } 344 368 345 369 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) { 346 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;370 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 347 371 } 348 372 349 373 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) { 350 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;374 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 351 375 } else { 352 376 /* apparently we can't do ntlmv2 if we don't do ntlm2 */ 353 gensec_ntlmssp_state->use_ntlmv2 = false;377 ntlmssp_state->use_ntlmv2 = false; 354 378 } 355 379 … … 364 388 * sealing. (It is actually pulled out and used directly) 365 389 */ 366 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;390 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 367 391 } 368 392 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 369 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;393 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 370 394 } 371 395 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 372 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 373 } 374 375 gensec_security->private_data = gensec_ntlmssp_state; 396 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 397 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 398 } 376 399 377 400 return NT_STATUS_OK; -
vendor/current/source4/auth/ntlmssp/ntlmssp_server.c
r414 r740 24 24 #include "includes.h" 25 25 #include "system/network.h" 26 #include "lib/tsocket/tsocket.h" 26 27 #include "auth/ntlmssp/ntlmssp.h" 27 #include "../librpc/gen_ndr/ntlmssp.h" 28 #include "../librpc/gen_ndr/ndr_ntlmssp.h" 29 #include "../libcli/auth/ntlmssp_ndr.h" 30 #include "../libcli/auth/ntlmssp_private.h" 28 31 #include "../libcli/auth/libcli_auth.h" 29 32 #include "../lib/crypto/crypto.h" 30 33 #include "auth/gensec/gensec.h" 34 #include "auth/gensec/gensec_proto.h" 31 35 #include "auth/auth.h" 32 #include "auth/ntlm/auth_proto.h"33 36 #include "param/param.h" 34 #include "auth/session_proto.h" 35 36 /** 37 * Set a username on an NTLMSSP context - ensures it is talloc()ed 38 * 39 */ 40 41 static NTSTATUS ntlmssp_set_username(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *user) 42 { 43 if (!user) { 44 /* it should be at least "" */ 45 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n")); 46 return NT_STATUS_INVALID_PARAMETER; 47 } 48 gensec_ntlmssp_state->user = talloc_strdup(gensec_ntlmssp_state, user); 49 if (!gensec_ntlmssp_state->user) { 50 return NT_STATUS_NO_MEMORY; 51 } 52 return NT_STATUS_OK; 53 } 54 55 /** 56 * Set a domain on an NTLMSSP context - ensures it is talloc()ed 57 * 58 */ 59 static NTSTATUS ntlmssp_set_domain(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *domain) 60 { 61 gensec_ntlmssp_state->domain = talloc_strdup(gensec_ntlmssp_state, domain); 62 if (!gensec_ntlmssp_state->domain) { 63 return NT_STATUS_NO_MEMORY; 64 } 65 return NT_STATUS_OK; 66 } 67 68 /** 69 * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 70 * 71 */ 72 static NTSTATUS ntlmssp_set_workstation(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *workstation) 73 { 74 gensec_ntlmssp_state->workstation = talloc_strdup(gensec_ntlmssp_state, workstation); 75 if (!gensec_ntlmssp_state->workstation) { 76 return NT_STATUS_NO_MEMORY; 77 } 78 return NT_STATUS_OK; 79 } 80 81 /** 82 * Determine correct target name flags for reply, given server role 83 * and negotiated flags 84 * 85 * @param gensec_ntlmssp_state NTLMSSP State 86 * @param neg_flags The flags from the packet 87 * @param chal_flags The flags to be set in the reply packet 88 * @return The 'target name' string. 89 */ 90 91 static const char *ntlmssp_target_name(struct gensec_ntlmssp_state *gensec_ntlmssp_state, 92 uint32_t neg_flags, uint32_t *chal_flags) 93 { 94 if (neg_flags & NTLMSSP_REQUEST_TARGET) { 95 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO; 96 *chal_flags |= NTLMSSP_REQUEST_TARGET; 97 if (gensec_ntlmssp_state->server_role == ROLE_STANDALONE) { 98 *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; 99 return gensec_ntlmssp_state->server_name; 100 } else { 101 *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; 102 return gensec_ntlmssp_state->domain; 103 }; 104 } else { 105 return ""; 106 } 107 } 108 109 110 111 /** 112 * Next state function for the Negotiate packet 113 * 37 38 /** 39 * Next state function for the Negotiate packet (GENSEC wrapper) 40 * 114 41 * @param gensec_security GENSEC state 115 42 * @param out_mem_ctx Memory context for *out 116 43 * @param in The request, as a DATA_BLOB. reply.data must be NULL 117 44 * @param out The reply, as an allocated DATA_BLOB, caller to free. 118 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required. 119 */ 120 121 NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security, 122 TALLOC_CTX *out_mem_ctx, 123 const DATA_BLOB in, DATA_BLOB *out) 124 { 125 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 126 DATA_BLOB struct_blob; 127 uint32_t neg_flags = 0; 128 uint32_t ntlmssp_command, chal_flags; 129 const uint8_t *cryptkey; 130 const char *target_name; 131 132 /* parse the NTLMSSP packet */ 133 #if 0 134 file_save("ntlmssp_negotiate.dat", request.data, request.length); 135 #endif 136 137 if (in.length) { 138 if ((in.length < 16) || !msrpc_parse(out_mem_ctx, 139 &in, "Cdd", 140 "NTLMSSP", 141 &ntlmssp_command, 142 &neg_flags)) { 143 DEBUG(1, ("ntlmssp_server_negotiate: failed to parse " 144 "NTLMSSP Negotiate of length %u:\n", 145 (unsigned int)in.length )); 146 dump_data(2, in.data, in.length); 147 return NT_STATUS_INVALID_PARAMETER; 148 } 149 debug_ntlmssp_flags(neg_flags); 150 } 151 152 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, neg_flags, gensec_ntlmssp_state->allow_lm_key); 153 154 /* Ask our caller what challenge they would like in the packet */ 155 cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state); 156 if (!cryptkey) { 157 DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n")); 158 return NT_STATUS_INTERNAL_ERROR; 159 } 160 161 /* Check if we may set the challenge */ 162 if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) { 163 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; 164 } 165 166 /* The flags we send back are not just the negotiated flags, 167 * they are also 'what is in this packet'. Therfore, we 168 * operate on 'chal_flags' from here on 169 */ 170 171 chal_flags = gensec_ntlmssp_state->neg_flags; 172 173 /* get the right name to fill in as 'target' */ 174 target_name = ntlmssp_target_name(gensec_ntlmssp_state, 175 neg_flags, &chal_flags); 176 if (target_name == NULL) 45 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required. 46 */ 47 48 NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security, 49 TALLOC_CTX *out_mem_ctx, 50 const DATA_BLOB request, DATA_BLOB *reply) 51 { 52 struct gensec_ntlmssp_context *gensec_ntlmssp = 53 talloc_get_type_abort(gensec_security->private_data, 54 struct gensec_ntlmssp_context); 55 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 56 return ntlmssp_server_negotiate(ntlmssp_state, out_mem_ctx, request, reply); 57 } 58 59 /** 60 * Next state function for the Authenticate packet (GENSEC wrapper) 61 * 62 * @param gensec_security GENSEC state 63 * @param out_mem_ctx Memory context for *out 64 * @param in The request, as a DATA_BLOB. reply.data must be NULL 65 * @param out The reply, as an allocated DATA_BLOB, caller to free. 66 * @return Errors or NT_STATUS_OK if authentication sucessful 67 */ 68 69 NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security, 70 TALLOC_CTX *out_mem_ctx, 71 const DATA_BLOB in, DATA_BLOB *out) 72 { 73 struct gensec_ntlmssp_context *gensec_ntlmssp = 74 talloc_get_type_abort(gensec_security->private_data, 75 struct gensec_ntlmssp_context); 76 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 77 return ntlmssp_server_auth(ntlmssp_state, out_mem_ctx, in, out); 78 } 79 80 /** 81 * Return the challenge as determined by the authentication subsystem 82 * @return an 8 byte random challenge 83 */ 84 85 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state, 86 uint8_t chal[8]) 87 { 88 struct gensec_ntlmssp_context *gensec_ntlmssp = 89 talloc_get_type_abort(ntlmssp_state->callback_private, 90 struct gensec_ntlmssp_context); 91 struct auth_context *auth_context = gensec_ntlmssp->auth_context; 92 NTSTATUS status; 93 94 status = auth_context->get_challenge(auth_context, chal); 95 if (!NT_STATUS_IS_OK(status)) { 96 DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n", 97 nt_errstr(status))); 98 return status; 99 } 100 101 return NT_STATUS_OK; 102 } 103 104 /** 105 * Some authentication methods 'fix' the challenge, so we may not be able to set it 106 * 107 * @return If the effective challenge used by the auth subsystem may be modified 108 */ 109 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) 110 { 111 struct gensec_ntlmssp_context *gensec_ntlmssp = 112 talloc_get_type_abort(ntlmssp_state->callback_private, 113 struct gensec_ntlmssp_context); 114 struct auth_context *auth_context = gensec_ntlmssp->auth_context; 115 116 return auth_context->challenge_may_be_modified(auth_context); 117 } 118 119 /** 120 * NTLM2 authentication modifies the effective challenge, 121 * @param challenge The new challenge value 122 */ 123 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) 124 { 125 struct gensec_ntlmssp_context *gensec_ntlmssp = 126 talloc_get_type_abort(ntlmssp_state->callback_private, 127 struct gensec_ntlmssp_context); 128 struct auth_context *auth_context = gensec_ntlmssp->auth_context; 129 NTSTATUS nt_status; 130 const uint8_t *chal; 131 132 if (challenge->length != 8) { 177 133 return NT_STATUS_INVALID_PARAMETER; 178 179 gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8); 180 gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8); 181 182 /* This creates the 'blob' of names that appears at the end of the packet */ 183 if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) { 134 } 135 136 chal = challenge->data; 137 138 nt_status = auth_context->set_challenge(auth_context, 139 chal, 140 "NTLMSSP callback (NTLM2)"); 141 142 return nt_status; 143 } 144 145 /** 146 * Check the password on an NTLMSSP login. 147 * 148 * Return the session keys used on the connection. 149 */ 150 151 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, 152 TALLOC_CTX *mem_ctx, 153 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 154 { 155 struct gensec_ntlmssp_context *gensec_ntlmssp = 156 talloc_get_type_abort(ntlmssp_state->callback_private, 157 struct gensec_ntlmssp_context); 158 struct auth_context *auth_context = gensec_ntlmssp->auth_context; 159 NTSTATUS nt_status; 160 struct auth_usersupplied_info *user_info; 161 162 user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info); 163 if (!user_info) { 164 return NT_STATUS_NO_MEMORY; 165 } 166 167 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; 168 user_info->flags = 0; 169 user_info->mapped_state = false; 170 user_info->client.account_name = ntlmssp_state->user; 171 user_info->client.domain_name = ntlmssp_state->domain; 172 user_info->workstation_name = ntlmssp_state->client.netbios_name; 173 user_info->remote_host = gensec_get_remote_address(gensec_ntlmssp->gensec_security); 174 175 user_info->password_state = AUTH_PASSWORD_RESPONSE; 176 user_info->password.response.lanman = ntlmssp_state->lm_resp; 177 user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data); 178 user_info->password.response.nt = ntlmssp_state->nt_resp; 179 user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data); 180 181 nt_status = auth_context->check_password(auth_context, 182 gensec_ntlmssp, 183 user_info, 184 &gensec_ntlmssp->user_info_dc); 185 talloc_free(user_info); 186 NT_STATUS_NOT_OK_RETURN(nt_status); 187 188 if (gensec_ntlmssp->user_info_dc->user_session_key.length) { 189 DEBUG(10, ("Got NT session key of length %u\n", 190 (unsigned)gensec_ntlmssp->user_info_dc->user_session_key.length)); 191 *user_session_key = gensec_ntlmssp->user_info_dc->user_session_key; 192 talloc_steal(mem_ctx, user_session_key->data); 193 gensec_ntlmssp->user_info_dc->user_session_key = data_blob_null; 194 } 195 if (gensec_ntlmssp->user_info_dc->lm_session_key.length) { 196 DEBUG(10, ("Got LM session key of length %u\n", 197 (unsigned)gensec_ntlmssp->user_info_dc->lm_session_key.length)); 198 *lm_session_key = gensec_ntlmssp->user_info_dc->lm_session_key; 199 talloc_steal(mem_ctx, lm_session_key->data); 200 gensec_ntlmssp->user_info_dc->lm_session_key = data_blob_null; 201 } 202 return nt_status; 203 } 204 205 /** 206 * Return the credentials of a logged on user, including session keys 207 * etc. 208 * 209 * Only valid after a successful authentication 210 * 211 * May only be called once per authentication. 212 * 213 */ 214 215 NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, 216 struct auth_session_info **session_info) 217 { 218 NTSTATUS nt_status; 219 struct gensec_ntlmssp_context *gensec_ntlmssp = 220 talloc_get_type_abort(gensec_security->private_data, 221 struct gensec_ntlmssp_context); 222 struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 223 224 nt_status = gensec_generate_session_info(ntlmssp_state, 225 gensec_security, 226 gensec_ntlmssp->user_info_dc, 227 session_info); 228 NT_STATUS_NOT_OK_RETURN(nt_status); 229 230 (*session_info)->session_key = data_blob_talloc(*session_info, 231 ntlmssp_state->session_key.data, 232 ntlmssp_state->session_key.length); 233 234 return NT_STATUS_OK; 235 } 236 237 /** 238 * Start NTLMSSP on the server side 239 * 240 */ 241 NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) 242 { 243 NTSTATUS nt_status; 244 struct ntlmssp_state *ntlmssp_state; 245 struct gensec_ntlmssp_context *gensec_ntlmssp; 246 247 nt_status = gensec_ntlmssp_start(gensec_security); 248 NT_STATUS_NOT_OK_RETURN(nt_status); 249 250 gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data, 251 struct gensec_ntlmssp_context); 252 ntlmssp_state = gensec_ntlmssp->ntlmssp_state; 253 254 ntlmssp_state->role = NTLMSSP_SERVER; 255 256 ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; 257 258 ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx) 259 && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false)); 260 261 ntlmssp_state->neg_flags = 262 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION; 263 264 ntlmssp_state->lm_resp = data_blob(NULL, 0); 265 ntlmssp_state->nt_resp = data_blob(NULL, 0); 266 267 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) { 268 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; 269 } 270 271 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) { 272 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; 273 } 274 275 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) { 276 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; 277 } 278 279 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) { 280 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 281 } 282 283 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) { 284 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; 285 } 286 287 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { 288 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; 289 } 290 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { 291 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 292 } 293 294 gensec_ntlmssp->auth_context = gensec_security->auth_context; 295 296 ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; 297 ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; 298 ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; 299 ntlmssp_state->check_password = auth_ntlmssp_check_password; 300 if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) { 301 ntlmssp_state->server.is_standalone = true; 302 } else { 303 ntlmssp_state->server.is_standalone = false; 304 } 305 306 ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx); 307 308 ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx); 309 310 { 184 311 char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN]; 185 const char *target_name_dns = "";186 312 187 313 /* Find out the DNS domain name */ 188 314 dnsdomname[0] = '\0'; 189 safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); 190 strlower_m(dnsdomname); 315 safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); 191 316 192 317 /* Find out the DNS host name */ 193 safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);318 safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1); 194 319 if (dnsdomname[0] != '\0') { 195 320 safe_strcat(dnsname, ".", sizeof(dnsname) - 1); … … 198 323 strlower_m(dnsname); 199 324 200 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { 201 target_name_dns = dnsdomname; 202 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { 203 target_name_dns = dnsname; 204 } 205 206 msrpc_gen(out_mem_ctx, 207 &struct_blob, "aaaaa", 208 MsvAvNbDomainName, target_name, 209 MsvAvNbComputerName, gensec_ntlmssp_state->server_name, 210 MsvAvDnsDomainName, dnsdomname, 211 MsvAvDnsComputerName, dnsname, 212 MsvAvEOL, ""); 213 } else { 214 struct_blob = data_blob(NULL, 0); 215 } 216 217 { 218 /* Marshal the packet in the right format, be it unicode or ASCII */ 219 const char *gen_string; 220 if (gensec_ntlmssp_state->unicode) { 221 gen_string = "CdUdbddB"; 222 } else { 223 gen_string = "CdAdbddB"; 224 } 225 226 msrpc_gen(out_mem_ctx, 227 out, gen_string, 228 "NTLMSSP", 229 NTLMSSP_CHALLENGE, 230 target_name, 231 chal_flags, 232 cryptkey, 8, 233 0, 0, 234 struct_blob.data, struct_blob.length); 235 } 236 237 gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH; 238 239 return NT_STATUS_MORE_PROCESSING_REQUIRED; 240 } 241 242 /** 243 * Next state function for the Authenticate packet 244 * 245 * @param gensec_ntlmssp_state NTLMSSP State 246 * @param request The request, as a DATA_BLOB 247 * @return Errors or NT_STATUS_OK. 248 */ 249 250 static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlmssp_state, 251 const DATA_BLOB request) 252 { 253 uint32_t ntlmssp_command, auth_flags; 254 NTSTATUS nt_status; 255 256 uint8_t session_nonce_hash[16]; 257 258 const char *parse_string; 259 char *domain = NULL; 260 char *user = NULL; 261 char *workstation = NULL; 262 263 #if 0 264 file_save("ntlmssp_auth.dat", request.data, request.length); 265 #endif 266 267 if (gensec_ntlmssp_state->unicode) { 268 parse_string = "CdBBUUUBd"; 269 } else { 270 parse_string = "CdBBAAABd"; 271 } 272 273 /* zero these out */ 274 data_blob_free(&gensec_ntlmssp_state->lm_resp); 275 data_blob_free(&gensec_ntlmssp_state->nt_resp); 276 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 277 278 gensec_ntlmssp_state->user = NULL; 279 gensec_ntlmssp_state->domain = NULL; 280 gensec_ntlmssp_state->workstation = NULL; 281 282 /* now the NTLMSSP encoded auth hashes */ 283 if (!msrpc_parse(gensec_ntlmssp_state, 284 &request, parse_string, 285 "NTLMSSP", 286 &ntlmssp_command, 287 &gensec_ntlmssp_state->lm_resp, 288 &gensec_ntlmssp_state->nt_resp, 289 &domain, 290 &user, 291 &workstation, 292 &gensec_ntlmssp_state->encrypted_session_key, 293 &auth_flags)) { 294 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n")); 295 dump_data(10, request.data, request.length); 296 297 /* zero this out */ 298 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 299 auth_flags = 0; 300 301 /* Try again with a shorter string (Win9X truncates this packet) */ 302 if (gensec_ntlmssp_state->unicode) { 303 parse_string = "CdBBUUU"; 304 } else { 305 parse_string = "CdBBAAA"; 306 } 307 308 /* now the NTLMSSP encoded auth hashes */ 309 if (!msrpc_parse(gensec_ntlmssp_state, 310 &request, parse_string, 311 "NTLMSSP", 312 &ntlmssp_command, 313 &gensec_ntlmssp_state->lm_resp, 314 &gensec_ntlmssp_state->nt_resp, 315 &domain, 316 &user, 317 &workstation)) { 318 DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); 319 dump_data(2, request.data, request.length); 320 321 return NT_STATUS_INVALID_PARAMETER; 322 } 323 } 324 325 if (auth_flags) 326 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, auth_flags, gensec_ntlmssp_state->allow_lm_key); 327 328 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(gensec_ntlmssp_state, domain))) { 329 /* zero this out */ 330 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 331 return nt_status; 332 } 333 334 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(gensec_ntlmssp_state, user))) { 335 /* zero this out */ 336 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 337 return nt_status; 338 } 339 340 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state, workstation))) { 341 /* zero this out */ 342 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 343 return nt_status; 344 } 345 346 DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", 347 gensec_ntlmssp_state->user, gensec_ntlmssp_state->domain, gensec_ntlmssp_state->workstation, (unsigned long)gensec_ntlmssp_state->lm_resp.length, (unsigned long)gensec_ntlmssp_state->nt_resp.length)); 348 349 #if 0 350 file_save("nthash1.dat", &gensec_ntlmssp_state->nt_resp.data, &gensec_ntlmssp_state->nt_resp.length); 351 file_save("lmhash1.dat", &gensec_ntlmssp_state->lm_resp.data, &gensec_ntlmssp_state->lm_resp.length); 352 #endif 353 354 /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a 355 client challenge 356 357 However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. 358 */ 359 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 360 if (gensec_ntlmssp_state->nt_resp.length == 24 && gensec_ntlmssp_state->lm_resp.length == 24) { 361 struct MD5Context md5_session_nonce_ctx; 362 SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data 363 && gensec_ntlmssp_state->internal_chal.length == 8); 364 365 gensec_ntlmssp_state->doing_ntlm2 = true; 366 367 memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8); 368 memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8); 369 370 MD5Init(&md5_session_nonce_ctx); 371 MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 16); 372 MD5Final(session_nonce_hash, &md5_session_nonce_ctx); 373 374 gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, 375 session_nonce_hash, 8); 376 377 /* LM response is no longer useful, zero it out */ 378 data_blob_free(&gensec_ntlmssp_state->lm_resp); 379 380 /* We changed the effective challenge - set it */ 381 if (!NT_STATUS_IS_OK(nt_status = 382 gensec_ntlmssp_state->set_challenge(gensec_ntlmssp_state, 383 &gensec_ntlmssp_state->chal))) { 384 /* zero this out */ 385 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key); 386 return nt_status; 387 } 388 389 /* LM Key is incompatible... */ 390 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; 391 } 392 } 325 ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state, 326 dnsname); 327 NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name); 328 329 ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state, 330 dnsdomname); 331 NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain); 332 } 333 393 334 return NT_STATUS_OK; 394 335 } 395 336 396 /**397 * Next state function for the Authenticate packet398 * (after authentication - figures out the session keys etc)399 *400 * @param gensec_ntlmssp_state NTLMSSP State401 * @return Errors or NT_STATUS_OK.402 */403 404 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,405 DATA_BLOB *user_session_key,406 DATA_BLOB *lm_session_key)407 {408 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;409 NTSTATUS nt_status;410 DATA_BLOB session_key = data_blob(NULL, 0);411 412 if (user_session_key)413 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);414 415 if (lm_session_key)416 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);417 418 /* Handle the different session key derivation for NTLM2 */419 if (gensec_ntlmssp_state->doing_ntlm2) {420 if (user_session_key && user_session_key->data && user_session_key->length == 16) {421 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);422 hmac_md5(user_session_key->data, gensec_ntlmssp_state->crypt.ntlm2.session_nonce,423 sizeof(gensec_ntlmssp_state->crypt.ntlm2.session_nonce), session_key.data);424 DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));425 dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);426 427 } else {428 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));429 session_key = data_blob(NULL, 0);430 }431 } else if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)432 /* Ensure we can never get here on NTLMv2 */433 && (gensec_ntlmssp_state->nt_resp.length == 0 || gensec_ntlmssp_state->nt_resp.length == 24)) {434 435 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {436 if (gensec_ntlmssp_state->lm_resp.data && gensec_ntlmssp_state->lm_resp.length == 24) {437 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);438 SMBsesskeygen_lm_sess_key(lm_session_key->data, gensec_ntlmssp_state->lm_resp.data,439 session_key.data);440 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));441 dump_data_pw("LM session key:\n", session_key.data, session_key.length);442 } else {443 444 /* When there is no LM response, just use zeros */445 static const uint8_t zeros[24];446 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);447 SMBsesskeygen_lm_sess_key(zeros, zeros,448 session_key.data);449 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));450 dump_data_pw("LM session key:\n", session_key.data, session_key.length);451 }452 } else {453 /* LM Key not selected */454 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;455 456 DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));457 session_key = data_blob(NULL, 0);458 }459 460 } else if (user_session_key && user_session_key->data) {461 session_key = data_blob_talloc(gensec_ntlmssp_state, user_session_key->data, user_session_key->length);462 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));463 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);464 465 /* LM Key not selected */466 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;467 468 } else if (lm_session_key && lm_session_key->data) {469 /* Very weird to have LM key, but no user session key, but anyway.. */470 session_key = data_blob_talloc(gensec_ntlmssp_state, lm_session_key->data, lm_session_key->length);471 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));472 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);473 474 /* LM Key not selected */475 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;476 477 } else {478 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));479 session_key = data_blob(NULL, 0);480 481 /* LM Key not selected */482 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;483 }484 485 /* With KEY_EXCH, the client supplies the proposed session key,486 but encrypts it with the long-term key */487 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {488 if (!gensec_ntlmssp_state->encrypted_session_key.data489 || gensec_ntlmssp_state->encrypted_session_key.length != 16) {490 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);491 DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",492 (unsigned)gensec_ntlmssp_state->encrypted_session_key.length));493 return NT_STATUS_INVALID_PARAMETER;494 } else if (!session_key.data || session_key.length != 16) {495 DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",496 (unsigned)session_key.length));497 gensec_ntlmssp_state->session_key = session_key;498 } else {499 dump_data_pw("KEY_EXCH session key (enc):\n",500 gensec_ntlmssp_state->encrypted_session_key.data,501 gensec_ntlmssp_state->encrypted_session_key.length);502 arcfour_crypt(gensec_ntlmssp_state->encrypted_session_key.data,503 session_key.data,504 gensec_ntlmssp_state->encrypted_session_key.length);505 gensec_ntlmssp_state->session_key = data_blob_talloc(gensec_ntlmssp_state,506 gensec_ntlmssp_state->encrypted_session_key.data,507 gensec_ntlmssp_state->encrypted_session_key.length);508 dump_data_pw("KEY_EXCH session key:\n", gensec_ntlmssp_state->encrypted_session_key.data,509 gensec_ntlmssp_state->encrypted_session_key.length);510 talloc_free(session_key.data);511 }512 } else {513 gensec_ntlmssp_state->session_key = session_key;514 }515 516 if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)517 || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {518 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);519 } else {520 nt_status = NT_STATUS_OK;521 }522 523 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);524 525 /* allow arbitarily many authentications, but watch that this will cause a526 memory leak, until the gensec_ntlmssp_state is shutdown527 */528 529 if (gensec_ntlmssp_state->server_multiple_authentications) {530 gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;531 } else {532 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;533 }534 535 return nt_status;536 }537 538 539 /**540 * Next state function for the Authenticate packet541 *542 * @param gensec_security GENSEC state543 * @param out_mem_ctx Memory context for *out544 * @param in The request, as a DATA_BLOB. reply.data must be NULL545 * @param out The reply, as an allocated DATA_BLOB, caller to free.546 * @return Errors or NT_STATUS_OK if authentication sucessful547 */548 549 NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security,550 TALLOC_CTX *out_mem_ctx,551 const DATA_BLOB in, DATA_BLOB *out)552 {553 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;554 DATA_BLOB user_session_key = data_blob(NULL, 0);555 DATA_BLOB lm_session_key = data_blob(NULL, 0);556 NTSTATUS nt_status;557 558 TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);559 if (!mem_ctx) {560 return NT_STATUS_NO_MEMORY;561 }562 563 /* zero the outbound NTLMSSP packet */564 *out = data_blob_talloc(out_mem_ctx, NULL, 0);565 566 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) {567 talloc_free(mem_ctx);568 return nt_status;569 }570 571 /*572 * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth573 * is required (by "ntlm auth = no" and "lm auth = no" being set in the574 * smb.conf file) and no NTLMv2 response was sent then the password check575 * will fail here. JRA.576 */577 578 /* Finally, actually ask if the password is OK */579 580 if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx,581 &user_session_key, &lm_session_key))) {582 talloc_free(mem_ctx);583 return nt_status;584 }585 586 if (gensec_security->want_features587 & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) {588 nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key);589 talloc_free(mem_ctx);590 return nt_status;591 } else {592 gensec_ntlmssp_state->session_key = data_blob(NULL, 0);593 talloc_free(mem_ctx);594 return NT_STATUS_OK;595 }596 }597 598 /**599 * Return the challenge as determined by the authentication subsystem600 * @return an 8 byte random challenge601 */602 603 static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)604 {605 NTSTATUS status;606 const uint8_t *chal;607 608 status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);609 if (!NT_STATUS_IS_OK(status)) {610 DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",611 nt_errstr(status)));612 return NULL;613 }614 615 return chal;616 }617 618 /**619 * Some authentication methods 'fix' the challenge, so we may not be able to set it620 *621 * @return If the effective challenge used by the auth subsystem may be modified622 */623 static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)624 {625 return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);626 }627 628 /**629 * NTLM2 authentication modifies the effective challenge,630 * @param challenge The new challenge value631 */632 static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *challenge)633 {634 NTSTATUS nt_status;635 struct auth_context *auth_context = gensec_ntlmssp_state->auth_context;636 const uint8_t *chal;637 638 if (challenge->length != 8) {639 return NT_STATUS_INVALID_PARAMETER;640 }641 642 chal = challenge->data;643 644 nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context,645 chal,646 "NTLMSSP callback (NTLM2)");647 648 return nt_status;649 }650 651 /**652 * Check the password on an NTLMSSP login.653 *654 * Return the session keys used on the connection.655 */656 657 static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state,658 TALLOC_CTX *mem_ctx,659 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)660 {661 NTSTATUS nt_status;662 struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info);663 if (!user_info) {664 return NT_STATUS_NO_MEMORY;665 }666 667 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;668 user_info->flags = 0;669 user_info->mapped_state = false;670 user_info->client.account_name = gensec_ntlmssp_state->user;671 user_info->client.domain_name = gensec_ntlmssp_state->domain;672 user_info->workstation_name = gensec_ntlmssp_state->workstation;673 user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security);674 675 user_info->password_state = AUTH_PASSWORD_RESPONSE;676 user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp;677 user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data);678 user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;679 user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);680 681 nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context,682 mem_ctx,683 user_info,684 &gensec_ntlmssp_state->server_info);685 talloc_free(user_info);686 NT_STATUS_NOT_OK_RETURN(nt_status);687 688 talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info);689 690 if (gensec_ntlmssp_state->server_info->user_session_key.length) {691 DEBUG(10, ("Got NT session key of length %u\n",692 (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length));693 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) {694 return NT_STATUS_NO_MEMORY;695 }696 697 *user_session_key = gensec_ntlmssp_state->server_info->user_session_key;698 }699 if (gensec_ntlmssp_state->server_info->lm_session_key.length) {700 DEBUG(10, ("Got LM session key of length %u\n",701 (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length));702 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) {703 return NT_STATUS_NO_MEMORY;704 }705 706 *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key;707 }708 return nt_status;709 }710 711 /**712 * Return the credentials of a logged on user, including session keys713 * etc.714 *715 * Only valid after a successful authentication716 *717 * May only be called once per authentication.718 *719 */720 721 NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,722 struct auth_session_info **session_info)723 {724 NTSTATUS nt_status;725 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;726 727 nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info);728 NT_STATUS_NOT_OK_RETURN(nt_status);729 730 (*session_info)->session_key = data_blob_talloc(*session_info,731 gensec_ntlmssp_state->session_key.data,732 gensec_ntlmssp_state->session_key.length);733 734 return NT_STATUS_OK;735 }736 737 /**738 * Start NTLMSSP on the server side739 *740 */741 NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)742 {743 NTSTATUS nt_status;744 struct gensec_ntlmssp_state *gensec_ntlmssp_state;745 746 nt_status = gensec_ntlmssp_start(gensec_security);747 NT_STATUS_NOT_OK_RETURN(nt_status);748 749 gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;750 751 gensec_ntlmssp_state->role = NTLMSSP_SERVER;752 753 gensec_ntlmssp_state->workstation = NULL;754 gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);755 756 gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);757 758 gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;759 760 gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx)761 && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));762 763 gensec_ntlmssp_state->server_multiple_authentications = false;764 765 gensec_ntlmssp_state->neg_flags =766 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;767 768 gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);769 gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);770 gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);771 772 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {773 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;774 }775 776 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {777 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;778 }779 780 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {781 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;782 }783 784 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {785 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;786 }787 788 if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {789 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;790 }791 792 if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {793 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;794 }795 if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {796 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;797 }798 799 gensec_ntlmssp_state->auth_context = gensec_security->auth_context;800 801 gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;802 gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;803 gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;804 gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;805 gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);806 807 return NT_STATUS_OK;808 }809 -
vendor/current/source4/auth/ntlmssp/ntlmssp_sign.c
r414 r740 1 /* 1 /* 2 2 * Unix SMB/CIFS implementation. 3 3 * Version 3.0 … … 5 5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 6 6 * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2005 7 * 7 * 8 8 * This program is free software; you can redistribute it and/or modify 9 9 * it under the terms of the GNU General Public License as published by 10 10 * the Free Software Foundation; either version 3 of the License, or 11 11 * (at your option) any later version. 12 * 12 * 13 13 * This program is distributed in the hope that it will be useful, 14 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 * GNU General Public License for more details. 17 * 17 * 18 18 * You should have received a copy of the GNU General Public License 19 19 * along with this program; if not, see <http://www.gnu.org/licenses/>. … … 22 22 #include "includes.h" 23 23 #include "auth/ntlmssp/ntlmssp.h" 24 #include "../librpc/gen_ndr/ntlmssp.h"25 #include "../libcli/auth/libcli_auth.h"26 #include "../lib/crypto/crypto.h"27 24 #include "auth/gensec/gensec.h" 25 #include "../libcli/auth/ntlmssp_private.h" 28 26 29 #define CLI_SIGN "session key to client-to-server signing key magic constant" 30 #define CLI_SEAL "session key to client-to-server sealing key magic constant" 31 #define SRV_SIGN "session key to server-to-client signing key magic constant" 32 #define SRV_SEAL "session key to server-to-client sealing key magic constant" 33 34 /** 35 * Some notes on the NTLM2 code: 36 * 37 * NTLM2 is a AEAD system. This means that the data encrypted is not 38 * all the data that is signed. In DCE-RPC case, the headers of the 39 * DCE-RPC packets are also signed. This prevents some of the 40 * fun-and-games one might have by changing them. 41 * 42 */ 43 44 static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx, 45 DATA_BLOB *subkey, 46 DATA_BLOB session_key, 47 const char *constant) 48 { 49 struct MD5Context ctx3; 50 *subkey = data_blob_talloc(mem_ctx, NULL, 16); 51 MD5Init(&ctx3); 52 MD5Update(&ctx3, session_key.data, session_key.length); 53 MD5Update(&ctx3, (const uint8_t *)constant, strlen(constant)+1); 54 MD5Final(subkey->data, &ctx3); 55 } 56 57 enum ntlmssp_direction { 58 NTLMSSP_SEND, 59 NTLMSSP_RECEIVE 60 }; 61 62 static NTSTATUS ntlmssp_make_packet_signature(struct gensec_ntlmssp_state *gensec_ntlmssp_state, 63 TALLOC_CTX *sig_mem_ctx, 64 const uint8_t *data, size_t length, 65 const uint8_t *whole_pdu, size_t pdu_length, 66 enum ntlmssp_direction direction, 67 DATA_BLOB *sig, bool encrypt_sig) 68 { 69 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 70 71 HMACMD5Context ctx; 72 uint8_t digest[16]; 73 uint8_t seq_num[4]; 74 75 *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE); 76 if (!sig->data) { 77 return NT_STATUS_NO_MEMORY; 78 } 79 80 switch (direction) { 81 case NTLMSSP_SEND: 82 SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.send_seq_num); 83 gensec_ntlmssp_state->crypt.ntlm2.send_seq_num++; 84 hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data, 85 gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length, &ctx); 86 break; 87 case NTLMSSP_RECEIVE: 88 SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num); 89 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num++; 90 hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 91 gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length, &ctx); 92 break; 93 } 94 hmac_md5_update(seq_num, sizeof(seq_num), &ctx); 95 hmac_md5_update(whole_pdu, pdu_length, &ctx); 96 hmac_md5_final(digest, &ctx); 97 98 if (encrypt_sig && gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { 99 switch (direction) { 100 case NTLMSSP_SEND: 101 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, digest, 8); 102 break; 103 case NTLMSSP_RECEIVE: 104 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, digest, 8); 105 break; 106 } 107 } 108 109 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); 110 memcpy(sig->data + 4, digest, 8); 111 memcpy(sig->data + 12, seq_num, 4); 112 113 DEBUG(10, ("NTLM2: created signature over %llu bytes of input:\n", (unsigned long long)pdu_length)); 114 dump_data(11, sig->data, sig->length); 115 116 } else { 117 uint32_t crc; 118 crc = crc32_calc_buffer(data, length); 119 if (!msrpc_gen(sig_mem_ctx, 120 sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) { 121 return NT_STATUS_NO_MEMORY; 122 } 123 gensec_ntlmssp_state->crypt.ntlm.seq_num++; 124 125 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4); 126 127 DEBUG(10, ("NTLM1: created signature over %llu bytes of input:\n", (unsigned long long)length)); 128 dump_data(11, sig->data, sig->length); 129 } 130 return NT_STATUS_OK; 131 } 132 133 /* TODO: make this non-public */ 134 NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, 135 TALLOC_CTX *sig_mem_ctx, 136 const uint8_t *data, size_t length, 137 const uint8_t *whole_pdu, size_t pdu_length, 27 NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security, 28 TALLOC_CTX *sig_mem_ctx, 29 const uint8_t *data, size_t length, 30 const uint8_t *whole_pdu, size_t pdu_length, 138 31 DATA_BLOB *sig) 139 32 { 140 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 141 142 return ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 143 data, length, 144 whole_pdu, pdu_length, 145 NTLMSSP_SEND, sig, true); 146 } 147 148 /** 149 * Check the signature of an incoming packet 150 * 151 */ 152 153 NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, 154 TALLOC_CTX *sig_mem_ctx, 155 const uint8_t *data, size_t length, 156 const uint8_t *whole_pdu, size_t pdu_length, 157 const DATA_BLOB *sig) 158 { 159 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 160 161 DATA_BLOB local_sig; 33 struct gensec_ntlmssp_context *gensec_ntlmssp = 34 talloc_get_type_abort(gensec_security->private_data, 35 struct gensec_ntlmssp_context); 162 36 NTSTATUS nt_status; 163 37 164 if (!gensec_ntlmssp_state->session_key.length) { 165 DEBUG(3, ("NO session key, cannot check packet signature\n")); 166 return NT_STATUS_NO_USER_SESSION_KEY; 167 } 168 169 nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 170 data, length, 171 whole_pdu, pdu_length, 172 NTLMSSP_RECEIVE, &local_sig, true); 173 174 if (!NT_STATUS_IS_OK(nt_status)) { 175 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); 176 return nt_status; 177 } 178 179 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 180 if (local_sig.length != sig->length || 181 memcmp(local_sig.data, 182 sig->data, sig->length) != 0) { 183 DEBUG(5, ("BAD SIG NTLM2: wanted signature over %llu bytes of input:\n", (unsigned long long)pdu_length)); 184 dump_data(5, local_sig.data, local_sig.length); 185 186 DEBUG(5, ("BAD SIG: got signature over %llu bytes of input:\n", (unsigned long long)pdu_length)); 187 dump_data(5, sig->data, sig->length); 188 189 DEBUG(1, ("NTLMSSP NTLM2 packet check failed due to invalid signature on %llu bytes of input!\n", (unsigned long long)pdu_length)); 190 return NT_STATUS_ACCESS_DENIED; 191 } 192 } else { 193 if (local_sig.length != sig->length || 194 memcmp(local_sig.data + 8, 195 sig->data + 8, sig->length - 8) != 0) { 196 DEBUG(5, ("BAD SIG NTLM1: wanted signature of %llu bytes of input:\n", (unsigned long long)length)); 197 dump_data(5, local_sig.data, local_sig.length); 198 199 DEBUG(5, ("BAD SIG: got signature of %llu bytes of input:\n", (unsigned long long)length)); 200 dump_data(5, sig->data, sig->length); 201 202 DEBUG(1, ("NTLMSSP NTLM1 packet check failed due to invalid signature on %llu bytes of input:\n", (unsigned long long)length)); 203 return NT_STATUS_ACCESS_DENIED; 204 } 205 } 206 dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length); 207 208 return NT_STATUS_OK; 209 } 210 211 212 /** 213 * Seal data with the NTLMSSP algorithm 214 * 215 */ 216 217 NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, 218 TALLOC_CTX *sig_mem_ctx, 219 uint8_t *data, size_t length, 220 const uint8_t *whole_pdu, size_t pdu_length, 221 DATA_BLOB *sig) 222 { 223 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 224 NTSTATUS nt_status; 225 if (!gensec_ntlmssp_state->session_key.length) { 226 DEBUG(3, ("NO session key, cannot seal packet\n")); 227 return NT_STATUS_NO_USER_SESSION_KEY; 228 } 229 230 DEBUG(10,("ntlmssp_seal_data: seal\n")); 231 dump_data_pw("ntlmssp clear data\n", data, length); 232 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 233 /* The order of these two operations matters - we must first seal the packet, 234 then seal the sequence number - this is becouse the send_seal_hash is not 235 constant, but is is rather updated with each iteration */ 236 nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx, 237 data, length, 238 whole_pdu, pdu_length, 239 NTLMSSP_SEND, sig, false); 240 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, data, length); 241 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { 242 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, sig->data+4, 8); 243 } 244 } else { 245 uint32_t crc; 246 crc = crc32_calc_buffer(data, length); 247 if (!msrpc_gen(sig_mem_ctx, 248 sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) { 249 return NT_STATUS_NO_MEMORY; 250 } 251 252 /* The order of these two operations matters - we must 253 first seal the packet, then seal the sequence 254 number - this is becouse the ntlmssp_hash is not 255 constant, but is is rather updated with each 256 iteration */ 257 258 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length); 259 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4); 260 /* increment counter on send */ 261 gensec_ntlmssp_state->crypt.ntlm.seq_num++; 262 nt_status = NT_STATUS_OK; 263 } 264 dump_data_pw("ntlmssp signature\n", sig->data, sig->length); 265 dump_data_pw("ntlmssp sealed data\n", data, length); 266 38 nt_status = ntlmssp_sign_packet(gensec_ntlmssp->ntlmssp_state, 39 sig_mem_ctx, 40 data, length, 41 whole_pdu, pdu_length, 42 sig); 267 43 268 44 return nt_status; 269 45 } 270 46 271 /** 272 * Unseal data with the NTLMSSP algorithm 273 * 274 */ 47 NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security, 48 TALLOC_CTX *sig_mem_ctx, 49 const uint8_t *data, size_t length, 50 const uint8_t *whole_pdu, size_t pdu_length, 51 const DATA_BLOB *sig) 52 { 53 struct gensec_ntlmssp_context *gensec_ntlmssp = 54 talloc_get_type_abort(gensec_security->private_data, 55 struct gensec_ntlmssp_context); 56 NTSTATUS nt_status; 57 58 nt_status = ntlmssp_check_packet(gensec_ntlmssp->ntlmssp_state, 59 data, length, 60 whole_pdu, pdu_length, 61 sig); 62 63 return nt_status; 64 } 65 66 NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security, 67 TALLOC_CTX *sig_mem_ctx, 68 uint8_t *data, size_t length, 69 const uint8_t *whole_pdu, size_t pdu_length, 70 DATA_BLOB *sig) 71 { 72 struct gensec_ntlmssp_context *gensec_ntlmssp = 73 talloc_get_type_abort(gensec_security->private_data, 74 struct gensec_ntlmssp_context); 75 NTSTATUS nt_status; 76 77 nt_status = ntlmssp_seal_packet(gensec_ntlmssp->ntlmssp_state, 78 sig_mem_ctx, 79 data, length, 80 whole_pdu, pdu_length, 81 sig); 82 83 return nt_status; 84 } 275 85 276 86 /* 277 87 wrappers for the ntlmssp_*() functions 278 88 */ 279 NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, 280 TALLOC_CTX *sig_mem_ctx, 281 uint8_t *data, size_t length, 282 const uint8_t *whole_pdu, size_t pdu_length, 89 NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, 90 TALLOC_CTX *sig_mem_ctx, 91 uint8_t *data, size_t length, 92 const uint8_t *whole_pdu, size_t pdu_length, 283 93 const DATA_BLOB *sig) 284 94 { 285 struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; 286 if (!gensec_ntlmssp_state->session_key.length) { 287 DEBUG(3, ("NO session key, cannot unseal packet\n")); 288 return NT_STATUS_NO_USER_SESSION_KEY; 289 } 95 struct gensec_ntlmssp_context *gensec_ntlmssp = 96 talloc_get_type_abort(gensec_security->private_data, 97 struct gensec_ntlmssp_context); 98 NTSTATUS nt_status; 290 99 291 dump_data_pw("ntlmssp sealed data\n", data, length); 292 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 293 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, data, length); 294 } else { 295 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length); 296 } 297 dump_data_pw("ntlmssp clear data\n", data, length); 298 return gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig); 299 } 100 nt_status = ntlmssp_unseal_packet(gensec_ntlmssp->ntlmssp_state, 101 data, length, 102 whole_pdu, pdu_length, 103 sig); 300 104 301 /** 302 Initialise the state for NTLMSSP signing. 303 */ 304 /* TODO: make this non-public */ 305 NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state) 306 { 307 TALLOC_CTX *mem_ctx = talloc_new(gensec_ntlmssp_state); 308 309 if (!mem_ctx) { 310 return NT_STATUS_NO_MEMORY; 311 } 312 313 DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); 314 debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags); 315 316 if (gensec_ntlmssp_state->session_key.length < 8) { 317 talloc_free(mem_ctx); 318 DEBUG(3, ("NO session key, cannot intialise signing\n")); 319 return NT_STATUS_NO_USER_SESSION_KEY; 320 } 321 322 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 323 { 324 DATA_BLOB weak_session_key = gensec_ntlmssp_state->session_key; 325 const char *send_sign_const; 326 const char *send_seal_const; 327 const char *recv_sign_const; 328 const char *recv_seal_const; 329 330 DATA_BLOB send_seal_key; 331 DATA_BLOB recv_seal_key; 332 333 switch (gensec_ntlmssp_state->role) { 334 case NTLMSSP_CLIENT: 335 send_sign_const = CLI_SIGN; 336 send_seal_const = CLI_SEAL; 337 recv_sign_const = SRV_SIGN; 338 recv_seal_const = SRV_SEAL; 339 break; 340 case NTLMSSP_SERVER: 341 send_sign_const = SRV_SIGN; 342 send_seal_const = SRV_SEAL; 343 recv_sign_const = CLI_SIGN; 344 recv_seal_const = CLI_SEAL; 345 break; 346 default: 347 talloc_free(mem_ctx); 348 return NT_STATUS_INTERNAL_ERROR; 349 } 350 351 gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state); 352 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state); 353 gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state); 354 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state); 355 356 /** 357 Weaken NTLMSSP keys to cope with down-level 358 clients, servers and export restrictions. 359 360 We probably should have some parameters to control 361 this, once we get NTLM2 working. 362 */ 363 364 /* Key weakening was not performed on the master key 365 * for NTLM2 (in ntlmssp_weaken_keys()), but must be 366 * done on the encryption subkeys only. That is why 367 * we don't have this code for the ntlmv1 case. 368 */ 369 370 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { 371 372 } else if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { 373 weak_session_key.length = 7; 374 } else { /* forty bits */ 375 weak_session_key.length = 5; 376 } 377 dump_data_pw("NTLMSSP weakend master key:\n", 378 weak_session_key.data, 379 weak_session_key.length); 380 381 /* SEND: sign key */ 382 calc_ntlmv2_key(gensec_ntlmssp_state, 383 &gensec_ntlmssp_state->crypt.ntlm2.send_sign_key, 384 gensec_ntlmssp_state->session_key, send_sign_const); 385 dump_data_pw("NTLMSSP send sign key:\n", 386 gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data, 387 gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length); 388 389 /* SEND: seal ARCFOUR pad */ 390 calc_ntlmv2_key(mem_ctx, 391 &send_seal_key, 392 weak_session_key, send_seal_const); 393 dump_data_pw("NTLMSSP send seal key:\n", 394 send_seal_key.data, 395 send_seal_key.length); 396 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, 397 &send_seal_key); 398 dump_data_pw("NTLMSSP send sesl hash:\n", 399 gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox, 400 sizeof(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox)); 401 402 /* RECV: sign key */ 403 calc_ntlmv2_key(gensec_ntlmssp_state, 404 &gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key, 405 gensec_ntlmssp_state->session_key, recv_sign_const); 406 dump_data_pw("NTLMSSP recv sign key:\n", 407 gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 408 gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length); 409 410 /* RECV: seal ARCFOUR pad */ 411 calc_ntlmv2_key(mem_ctx, 412 &recv_seal_key, 413 weak_session_key, recv_seal_const); 414 dump_data_pw("NTLMSSP recv seal key:\n", 415 recv_seal_key.data, 416 recv_seal_key.length); 417 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, 418 &recv_seal_key); 419 dump_data_pw("NTLMSSP receive seal hash:\n", 420 gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox, 421 sizeof(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox)); 422 423 gensec_ntlmssp_state->crypt.ntlm2.send_seq_num = 0; 424 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = 0; 425 426 } else { 427 DATA_BLOB weak_session_key = ntlmssp_weakend_key(gensec_ntlmssp_state, mem_ctx); 428 DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); 429 430 gensec_ntlmssp_state->crypt.ntlm.arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state); 431 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm.arcfour_state); 432 433 arcfour_init(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, 434 &weak_session_key); 435 dump_data_pw("NTLMSSP hash:\n", gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox, 436 sizeof(gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox)); 437 438 gensec_ntlmssp_state->crypt.ntlm.seq_num = 0; 439 } 440 441 talloc_free(mem_ctx); 442 return NT_STATUS_OK; 105 return nt_status; 443 106 } 444 107 … … 449 112 450 113 NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security, 451 TALLOC_CTX * sig_mem_ctx,114 TALLOC_CTX *out_mem_ctx, 452 115 const DATA_BLOB *in, 453 116 DATA_BLOB *out) 454 117 { 455 DATA_BLOB sig; 456 NTSTATUS nt_status; 118 struct gensec_ntlmssp_context *gensec_ntlmssp = 119 talloc_get_type_abort(gensec_security->private_data, 120 struct gensec_ntlmssp_context); 457 121 458 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 459 460 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); 461 if (!out->data) { 462 return NT_STATUS_NO_MEMORY; 463 } 464 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); 465 466 nt_status = gensec_ntlmssp_seal_packet(gensec_security, sig_mem_ctx, 467 out->data + NTLMSSP_SIG_SIZE, 468 out->length - NTLMSSP_SIG_SIZE, 469 out->data + NTLMSSP_SIG_SIZE, 470 out->length - NTLMSSP_SIG_SIZE, 471 &sig); 472 473 if (NT_STATUS_IS_OK(nt_status)) { 474 memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); 475 } 476 return nt_status; 477 478 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 479 480 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE); 481 if (!out->data) { 482 return NT_STATUS_NO_MEMORY; 483 } 484 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length); 485 486 nt_status = gensec_ntlmssp_sign_packet(gensec_security, sig_mem_ctx, 487 out->data + NTLMSSP_SIG_SIZE, 488 out->length - NTLMSSP_SIG_SIZE, 489 out->data + NTLMSSP_SIG_SIZE, 490 out->length - NTLMSSP_SIG_SIZE, 491 &sig); 492 493 if (NT_STATUS_IS_OK(nt_status)) { 494 memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE); 495 } 496 return nt_status; 497 498 } else { 499 *out = *in; 500 return NT_STATUS_OK; 501 } 122 return ntlmssp_wrap(gensec_ntlmssp->ntlmssp_state, 123 out_mem_ctx, 124 in, out); 502 125 } 503 126 504 127 505 128 NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security, 506 TALLOC_CTX * sig_mem_ctx,129 TALLOC_CTX *out_mem_ctx, 507 130 const DATA_BLOB *in, 508 131 DATA_BLOB *out) 509 132 { 510 DATA_BLOB sig; 133 struct gensec_ntlmssp_context *gensec_ntlmssp = 134 talloc_get_type_abort(gensec_security->private_data, 135 struct gensec_ntlmssp_context); 511 136 512 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { 513 if (in->length < NTLMSSP_SIG_SIZE) { 514 return NT_STATUS_INVALID_PARAMETER; 515 } 516 sig.data = in->data; 517 sig.length = NTLMSSP_SIG_SIZE; 518 519 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); 520 521 return gensec_ntlmssp_unseal_packet(gensec_security, sig_mem_ctx, 522 out->data, out->length, 523 out->data, out->length, 524 &sig); 525 526 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { 527 struct gensec_ntlmssp_state *gensec_ntlmssp_state = 528 (struct gensec_ntlmssp_state *)gensec_security->private_data; 529 NTSTATUS status; 530 uint32_t ntlm_seqnum; 531 struct arcfour_state ntlm_state; 532 uint32_t ntlm2_seqnum_r; 533 uint8_t ntlm2_key_r[16]; 534 struct arcfour_state ntlm2_state_r; 535 536 if (in->length < NTLMSSP_SIG_SIZE) { 537 return NT_STATUS_INVALID_PARAMETER; 538 } 539 sig.data = in->data; 540 sig.length = NTLMSSP_SIG_SIZE; 541 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE); 542 543 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 544 ntlm2_seqnum_r = gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num; 545 ntlm2_state_r = *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state; 546 memcpy(ntlm2_key_r, 547 gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 548 16); 549 } else { 550 ntlm_seqnum = gensec_ntlmssp_state->crypt.ntlm.seq_num; 551 ntlm_state = *gensec_ntlmssp_state->crypt.ntlm.arcfour_state; 552 } 553 554 status = gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, 555 out->data, out->length, 556 out->data, out->length, 557 &sig); 558 if (!NT_STATUS_IS_OK(status)) { 559 NTSTATUS check_status = status; 560 /* 561 * The Windows LDAP libraries seems to have a bug 562 * and always use sealing even if only signing was 563 * negotiated. So we need to fallback. 564 */ 565 566 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { 567 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = ntlm2_seqnum_r; 568 *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = ntlm2_state_r; 569 memcpy(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data, 570 ntlm2_key_r, 16); 571 } else { 572 gensec_ntlmssp_state->crypt.ntlm.seq_num = ntlm_seqnum; 573 *gensec_ntlmssp_state->crypt.ntlm.arcfour_state = ntlm_state; 574 } 575 576 status = gensec_ntlmssp_unseal_packet(gensec_security, 577 sig_mem_ctx, 578 out->data, 579 out->length, 580 out->data, 581 out->length, 582 &sig); 583 if (NT_STATUS_IS_OK(status)) { 584 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; 585 } else { 586 status = check_status; 587 } 588 } 589 return status; 590 } else { 591 *out = *in; 592 return NT_STATUS_OK; 593 } 137 return ntlmssp_unwrap(gensec_ntlmssp->ntlmssp_state, 138 out_mem_ctx, 139 in, out); 594 140 } 595 -
vendor/current/source4/auth/pyauth.c
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008 4 4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2011 5 5 6 This program is free software; you can redistribute it and/or modify 6 7 it under the terms of the GNU General Public License as published by … … 17 18 */ 18 19 20 #include <Python.h> 19 21 #include "includes.h" 22 #include "libcli/util/pyerrors.h" 20 23 #include "param/param.h" 21 24 #include "pyauth.h" 25 #include "pyldb.h" 22 26 #include "auth/system_session_proto.h" 27 #include "auth/auth.h" 23 28 #include "param/pyparam.h" 24 29 #include "libcli/security/security.h" 25 26 27 PyTypeObject PyAuthSession = { 30 #include "auth/credentials/pycredentials.h" 31 #include <tevent.h> 32 #include "librpc/rpc/pyrpc_util.h" 33 34 staticforward PyTypeObject PyAuthContext; 35 36 /* There's no Py_ssize_t in 2.4, apparently */ 37 #if PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION < 5 38 typedef int Py_ssize_t; 39 typedef inquiry lenfunc; 40 typedef intargfunc ssizeargfunc; 41 #endif 42 43 #ifndef Py_RETURN_NONE 44 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None 45 #endif 46 47 static PyObject *py_auth_session_get_security_token(PyObject *self, void *closure) 48 { 49 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 50 PyObject *py_security_token; 51 py_security_token = py_return_ndr_struct("samba.dcerpc.security", "token", 52 session->security_token, session->security_token); 53 return py_security_token; 54 } 55 56 static int py_auth_session_set_security_token(PyObject *self, PyObject *value, void *closure) 57 { 58 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 59 session->security_token = talloc_reference(session, py_talloc_get_ptr(value)); 60 return 0; 61 } 62 63 static PyObject *py_auth_session_get_session_key(PyObject *self, void *closure) 64 { 65 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 66 return PyString_FromStringAndSize((char *)session->session_key.data, session->session_key.length); 67 } 68 69 static int py_auth_session_set_session_key(PyObject *self, PyObject *value, void *closure) 70 { 71 DATA_BLOB val; 72 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 73 val.data = (uint8_t *)PyString_AsString(value); 74 val.length = PyString_Size(value); 75 76 session->session_key = data_blob_talloc(session, val.data, val.length); 77 return 0; 78 } 79 80 static PyObject *py_auth_session_get_credentials(PyObject *self, void *closure) 81 { 82 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 83 PyObject *py_credentials; 84 /* This is evil, as the credentials are not IDL structures */ 85 py_credentials = py_return_ndr_struct("samba.credentials", "Credentials", session->credentials, session->credentials); 86 return py_credentials; 87 } 88 89 static int py_auth_session_set_credentials(PyObject *self, PyObject *value, void *closure) 90 { 91 struct auth_session_info *session = py_talloc_get_type(self, struct auth_session_info); 92 session->credentials = talloc_reference(session, PyCredentials_AsCliCredentials(value)); 93 return 0; 94 } 95 96 static PyGetSetDef py_auth_session_getset[] = { 97 { discard_const_p(char, "security_token"), (getter)py_auth_session_get_security_token, (setter)py_auth_session_set_security_token, NULL }, 98 { discard_const_p(char, "session_key"), (getter)py_auth_session_get_session_key, (setter)py_auth_session_set_session_key, NULL }, 99 { discard_const_p(char, "credentials"), (getter)py_auth_session_get_credentials, (setter)py_auth_session_set_credentials, NULL }, 100 { NULL } 101 }; 102 103 static PyTypeObject PyAuthSession = { 28 104 .tp_name = "AuthSession", 29 105 .tp_basicsize = sizeof(py_talloc_Object), 30 .tp_dealloc = py_talloc_dealloc,31 106 .tp_flags = Py_TPFLAGS_DEFAULT, 32 .tp_ repr = py_talloc_default_repr,107 .tp_getset = py_auth_session_getset, 33 108 }; 34 109 … … 43 118 struct loadparm_context *lp_ctx = NULL; 44 119 struct auth_session_info *session; 120 TALLOC_CTX *mem_ctx; 45 121 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) 46 122 return NULL; 47 123 48 lp_ctx = lp_from_py_object(py_lp_ctx); 49 if (lp_ctx == NULL) 50 return NULL; 51 52 session = system_session(NULL, lp_ctx); 124 mem_ctx = talloc_new(NULL); 125 if (mem_ctx == NULL) { 126 PyErr_NoMemory(); 127 return NULL; 128 } 129 130 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 131 if (lp_ctx == NULL) { 132 talloc_free(mem_ctx); 133 return NULL; 134 } 135 136 session = system_session(lp_ctx); 137 138 talloc_free(mem_ctx); 53 139 54 140 return PyAuthSession_FromSession(session); 55 141 } 56 142 57 58 static PyObject *py_system_session_anon(PyObject *module, PyObject *args)59 {60 PyObject *py_lp_ctx = Py_None;61 struct loadparm_context *lp_ctx;62 struct auth_session_info *session;63 if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx))64 return NULL;65 66 lp_ctx = lp_from_py_object(py_lp_ctx);67 if (lp_ctx == NULL)68 return NULL;69 70 session = system_session_anon(NULL, lp_ctx);71 72 return PyAuthSession_FromSession(session);73 }74 143 75 144 static PyObject *py_admin_session(PyObject *module, PyObject *args) … … 80 149 struct auth_session_info *session; 81 150 struct dom_sid *domain_sid = NULL; 151 TALLOC_CTX *mem_ctx; 152 82 153 if (!PyArg_ParseTuple(args, "OO", &py_lp_ctx, &py_sid)) 83 154 return NULL; 84 155 85 lp_ctx = lp_from_py_object(py_lp_ctx); 86 if (lp_ctx == NULL) 87 return NULL; 88 89 domain_sid = dom_sid_parse_talloc(NULL, PyString_AsString(py_sid)); 156 mem_ctx = talloc_new(NULL); 157 if (mem_ctx == NULL) { 158 PyErr_NoMemory(); 159 return NULL; 160 } 161 162 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 163 if (lp_ctx == NULL) { 164 talloc_free(mem_ctx); 165 return NULL; 166 } 167 168 domain_sid = dom_sid_parse_talloc(mem_ctx, PyString_AsString(py_sid)); 169 if (domain_sid == NULL) { 170 PyErr_Format(PyExc_RuntimeError, "Unable to parse sid %s", 171 PyString_AsString(py_sid)); 172 talloc_free(mem_ctx); 173 return NULL; 174 } 90 175 session = admin_session(NULL, lp_ctx, domain_sid); 176 talloc_free(mem_ctx); 91 177 92 178 return PyAuthSession_FromSession(session); 93 179 } 180 181 static PyObject *py_user_session(PyObject *module, PyObject *args, PyObject *kwargs) 182 { 183 NTSTATUS nt_status; 184 struct auth_session_info *session; 185 TALLOC_CTX *mem_ctx; 186 const char * const kwnames[] = { "ldb", "lp_ctx", "principal", "dn", "session_info_flags", NULL }; 187 struct ldb_context *ldb_ctx; 188 PyObject *py_ldb = Py_None; 189 PyObject *py_dn = Py_None; 190 PyObject *py_lp_ctx = Py_None; 191 struct loadparm_context *lp_ctx = NULL; 192 struct ldb_dn *user_dn; 193 char *principal = NULL; 194 int session_info_flags = 0; /* This is an int, because that's 195 * what we need for the python 196 * PyArg_ParseTupleAndKeywords */ 197 198 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OzOi", 199 discard_const_p(char *, kwnames), 200 &py_ldb, &py_lp_ctx, &principal, &py_dn, &session_info_flags)) { 201 return NULL; 202 } 203 204 mem_ctx = talloc_new(NULL); 205 if (mem_ctx == NULL) { 206 PyErr_NoMemory(); 207 return NULL; 208 } 209 210 ldb_ctx = PyLdb_AsLdbContext(py_ldb); 211 212 if (py_dn == Py_None) { 213 user_dn = NULL; 214 } else { 215 if (!PyObject_AsDn(ldb_ctx, py_dn, ldb_ctx, &user_dn)) { 216 talloc_free(mem_ctx); 217 return NULL; 218 } 219 } 220 221 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 222 if (lp_ctx == NULL) { 223 talloc_free(mem_ctx); 224 return NULL; 225 } 226 227 nt_status = authsam_get_session_info_principal(mem_ctx, lp_ctx, ldb_ctx, principal, user_dn, 228 session_info_flags, &session); 229 if (!NT_STATUS_IS_OK(nt_status)) { 230 talloc_free(mem_ctx); 231 PyErr_NTSTATUS_IS_ERR_RAISE(nt_status); 232 } 233 234 talloc_steal(NULL, session); 235 talloc_free(mem_ctx); 236 237 return PyAuthSession_FromSession(session); 238 } 239 240 241 static const char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, 242 const char *paramname) 243 { 244 const char **ret; 245 Py_ssize_t i; 246 if (!PyList_Check(list)) { 247 PyErr_Format(PyExc_TypeError, "%s is not a list", paramname); 248 return NULL; 249 } 250 ret = talloc_array(NULL, const char *, PyList_Size(list)+1); 251 if (ret == NULL) { 252 PyErr_NoMemory(); 253 return NULL; 254 } 255 256 for (i = 0; i < PyList_Size(list); i++) { 257 PyObject *item = PyList_GetItem(list, i); 258 if (!PyString_Check(item)) { 259 PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); 260 return NULL; 261 } 262 ret[i] = talloc_strndup(ret, PyString_AsString(item), 263 PyString_Size(item)); 264 } 265 ret[i] = NULL; 266 return ret; 267 } 268 269 static PyObject *PyAuthContext_FromContext(struct auth_context *auth_context) 270 { 271 return py_talloc_reference(&PyAuthContext, auth_context); 272 } 273 274 static PyObject *py_auth_context_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) 275 { 276 PyObject *py_lp_ctx = Py_None; 277 PyObject *py_ldb = Py_None; 278 PyObject *py_messaging_ctx = Py_None; 279 PyObject *py_auth_context = Py_None; 280 PyObject *py_methods = Py_None; 281 TALLOC_CTX *mem_ctx; 282 struct auth_context *auth_context; 283 struct messaging_context *messaging_context = NULL; 284 struct loadparm_context *lp_ctx; 285 struct tevent_context *ev; 286 struct ldb_context *ldb; 287 NTSTATUS nt_status; 288 const char **methods; 289 290 const char * const kwnames[] = { "lp_ctx", "messaging_ctx", "ldb", "methods", NULL }; 291 292 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOO", 293 discard_const_p(char *, kwnames), 294 &py_lp_ctx, &py_messaging_ctx, &py_ldb, &py_methods)) 295 return NULL; 296 297 mem_ctx = talloc_new(NULL); 298 if (mem_ctx == NULL) { 299 PyErr_NoMemory(); 300 return NULL; 301 } 302 303 if (py_ldb != Py_None) { 304 ldb = PyLdb_AsLdbContext(py_ldb); 305 } 306 307 lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); 308 309 ev = tevent_context_init(mem_ctx); 310 if (ev == NULL) { 311 PyErr_NoMemory(); 312 return NULL; 313 } 314 315 if (py_messaging_ctx != Py_None) { 316 messaging_context = py_talloc_get_type(py_messaging_ctx, struct messaging_context); 317 } 318 319 if (py_methods == Py_None && py_ldb == Py_None) { 320 nt_status = auth_context_create(mem_ctx, ev, messaging_context, lp_ctx, &auth_context); 321 } else { 322 if (py_methods != Py_None) { 323 methods = PyList_AsStringList(mem_ctx, py_methods, "methods"); 324 if (methods == NULL) { 325 talloc_free(mem_ctx); 326 return NULL; 327 } 328 } else { 329 methods = auth_methods_from_lp(mem_ctx, lp_ctx); 330 } 331 nt_status = auth_context_create_methods(mem_ctx, methods, ev, 332 messaging_context, lp_ctx, 333 ldb, &auth_context); 334 } 335 336 if (!NT_STATUS_IS_OK(nt_status)) { 337 talloc_free(mem_ctx); 338 PyErr_NTSTATUS_IS_ERR_RAISE(nt_status); 339 } 340 341 if (!talloc_reference(auth_context, lp_ctx)) { 342 talloc_free(mem_ctx); 343 PyErr_NoMemory(); 344 return NULL; 345 } 346 347 if (!talloc_reference(auth_context, ev)) { 348 talloc_free(mem_ctx); 349 PyErr_NoMemory(); 350 return NULL; 351 } 352 353 py_auth_context = PyAuthContext_FromContext(auth_context); 354 355 talloc_free(mem_ctx); 356 357 return py_auth_context; 358 } 359 360 static PyTypeObject PyAuthContext = { 361 .tp_name = "AuthContext", 362 .tp_basicsize = sizeof(py_talloc_Object), 363 .tp_flags = Py_TPFLAGS_DEFAULT, 364 .tp_new = py_auth_context_new, 365 .tp_basicsize = sizeof(py_talloc_Object), 366 }; 94 367 95 368 static PyMethodDef py_auth_methods[] = { 96 369 { "system_session", (PyCFunction)py_system_session, METH_VARARGS, NULL }, 97 { "system_session_anonymous", (PyCFunction)py_system_session_anon, METH_VARARGS, NULL },98 370 { "admin_session", (PyCFunction)py_admin_session, METH_VARARGS, NULL }, 371 { "user_session", (PyCFunction)py_user_session, METH_VARARGS|METH_KEYWORDS, NULL }, 99 372 { NULL }, 100 373 }; … … 104 377 PyObject *m; 105 378 379 PyAuthSession.tp_base = PyTalloc_GetObjectType(); 380 if (PyAuthSession.tp_base == NULL) 381 return; 382 106 383 if (PyType_Ready(&PyAuthSession) < 0) 107 384 return; 108 385 109 m = Py_InitModule3("auth", py_auth_methods, "Authentication and authorization support."); 386 PyAuthContext.tp_base = PyTalloc_GetObjectType(); 387 if (PyAuthContext.tp_base == NULL) 388 return; 389 390 if (PyType_Ready(&PyAuthContext) < 0) 391 return; 392 393 m = Py_InitModule3("auth", py_auth_methods, 394 "Authentication and authorization support."); 110 395 if (m == NULL) 111 396 return; … … 113 398 Py_INCREF(&PyAuthSession); 114 399 PyModule_AddObject(m, "AuthSession", (PyObject *)&PyAuthSession); 115 } 400 Py_INCREF(&PyAuthContext); 401 PyModule_AddObject(m, "AuthContext", (PyObject *)&PyAuthContext); 402 403 #define ADD_FLAG(val) PyModule_AddObject(m, #val, PyInt_FromLong(val)) 404 ADD_FLAG(AUTH_SESSION_INFO_DEFAULT_GROUPS); 405 ADD_FLAG(AUTH_SESSION_INFO_AUTHENTICATED); 406 ADD_FLAG(AUTH_SESSION_INFO_SIMPLE_PRIVILEGES); 407 408 } -
vendor/current/source4/auth/pyauth.h
r414 r740 21 21 #define _PYAUTH_H_ 22 22 23 #include "pytalloc.h"23 #include <pytalloc.h> 24 24 #include "auth/session.h" 25 25 26 PyAPI_DATA(PyTypeObject) PyAuthSession;27 26 #define PyAuthSession_AsSession(obj) py_talloc_get_type(obj, struct auth_session_info) 28 27 #define PyAuthSession_Check(obj) PyObject_TypeCheck(obj, &PyAuthSession) -
vendor/current/source4/auth/sam.c
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 Password and authentication handling 4 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-20 044 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2001-2010 5 5 Copyright (C) Gerald Carter 2003 6 6 Copyright (C) Stefan Metzmacher 2005 … … 25 25 #include "auth/auth.h" 26 26 #include <ldb.h> 27 #include "../lib/util/util_ldb.h"28 27 #include "dsdb/samdb/samdb.h" 29 28 #include "libcli/security/security.h" 30 #include "libcli/ldap/ldap.h" 31 #include "../libcli/ldap/ldap_ndr.h" 32 #include "librpc/gen_ndr/ndr_netlogon.h" 33 #include "librpc/gen_ndr/ndr_security.h" 29 #include "auth/auth_sam.h" 30 #include "dsdb/common/util.h" 31 #include "libcli/ldap/ldap_ndr.h" 34 32 #include "param/param.h" 35 #include "auth/auth_sam.h"36 33 37 34 #define KRBTGT_ATTRS \ … … 42 39 "servicePrincipalName", \ 43 40 "msDS-KeyVersionNumber", \ 41 "msDS-SecondaryKrbTgtNumber", \ 42 "msDS-SupportedEncryptionTypes", \ 44 43 "supplementalCredentials", \ 45 44 \ … … 52 51 \ 53 52 "pwdLastSet", \ 54 "accountExpires" 53 "accountExpires" 55 54 56 55 const char *krbtgt_attrs[] = { 57 KRBTGT_ATTRS 56 KRBTGT_ATTRS, NULL 58 57 }; 59 58 60 59 const char *server_attrs[] = { 61 KRBTGT_ATTRS 60 KRBTGT_ATTRS, NULL 62 61 }; 63 62 … … 70 69 "userWorkstations", 71 70 72 /* required for server_info, not access control: */71 /* required for user_info_dc, not access control: */ 73 72 "displayName", 74 73 "scriptPath", … … 149 148 150 149 /**************************************************************************** 151 Do a specific test for a SAM_ACCOUNT being va ild for this connection150 Do a specific test for a SAM_ACCOUNT being valid for this connection 152 151 (ie not disabled, expired and the like). 153 152 ****************************************************************************/ … … 179 178 domain_dn, msg); 180 179 181 workstation_list = samdb_result_string(msg, "userWorkstations", NULL);180 workstation_list = ldb_msg_find_attr_as_string(msg, "userWorkstations", NULL); 182 181 183 182 /* Quit if the account was disabled. */ 184 183 if (acct_flags & ACB_DISABLED) { 185 DEBUG( 1,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs));184 DEBUG(2,("authsam_account_ok: Account for user '%s' was disabled.\n", name_for_logs)); 186 185 return NT_STATUS_ACCOUNT_DISABLED; 187 186 } … … 189 188 /* Quit if the account was locked out. */ 190 189 if (acct_flags & ACB_AUTOLOCK) { 191 DEBUG( 1,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs));190 DEBUG(2,("authsam_account_ok: Account for user %s was locked out.\n", name_for_logs)); 192 191 return NT_STATUS_ACCOUNT_LOCKED_OUT; 193 192 } … … 196 195 unix_to_nt_time(&now, time(NULL)); 197 196 if (now > acct_expiry) { 198 DEBUG( 1,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs));197 DEBUG(2,("authsam_account_ok: Account for user '%s' has expired.\n", name_for_logs)); 199 198 DEBUG(3,("authsam_account_ok: Account expired at '%s'.\n", 200 199 nt_time_string(mem_ctx, acct_expiry))); … … 204 203 /* check for immediate expiry "must change at next logon" (but not if this is a password change request) */ 205 204 if ((must_change_time == 0) && !password_change) { 206 DEBUG( 1,("sam_account_ok: Account for user '%s' password must change!.\n",205 DEBUG(2,("sam_account_ok: Account for user '%s' password must change!.\n", 207 206 name_for_logs)); 208 207 return NT_STATUS_PASSWORD_MUST_CHANGE; … … 211 210 /* check for expired password (but not if this is a password change request) */ 212 211 if ((must_change_time < now) && !password_change) { 213 DEBUG( 1,("sam_account_ok: Account for user '%s' password expired!.\n",212 DEBUG(2,("sam_account_ok: Account for user '%s' password expired!.\n", 214 213 name_for_logs)); 215 DEBUG( 1,("sam_account_ok: Password expired at '%s' unix time.\n",214 DEBUG(2,("sam_account_ok: Password expired at '%s' unix time.\n", 216 215 nt_time_string(mem_ctx, must_change_time))); 217 216 return NT_STATUS_PASSWORD_EXPIRED; … … 269 268 } 270 269 271 /* This function tests if a SID structure "sids" contains the SID "sid" */ 272 static bool sids_contains_sid(const struct dom_sid **sids, const int num_sids, 273 const struct dom_sid *sid) 274 { 275 int i; 276 277 for (i = 0; i < num_sids; i++) { 278 if (dom_sid_equal(sids[i], sid)) 279 return true; 280 } 281 return false; 282 } 283 284 /* 285 * This function generates the transitive closure of a given SID "sid" (it 286 * basically expands nested groups of a SID). 287 * If the SID isn't located in the "res_sids" structure yet and the 288 * "only_childs" flag is negative, we add it to "res_sids". 289 * Then we've always to consider the "memberOf" attributes. We invoke the 290 * function recursively on each item of it with the "only_childs" flag set to 291 * "false". 292 * The "only_childs" flag is particularly useful if you have a user SID and 293 * want to include all his groups (referenced with "memberOf") without his SID 294 * itself. 295 * 296 * At the beginning "res_sids" should reference to a NULL pointer. 297 */ 298 static NTSTATUS authsam_expand_nested_groups(struct ldb_context *sam_ctx, 299 const struct dom_sid *sid, const bool only_childs, 300 TALLOC_CTX *res_sids_ctx, struct dom_sid ***res_sids, 301 int *num_res_sids) 302 { 303 const char * const attrs[] = { "memberOf", NULL }; 304 int i, ret; 305 bool already_there; 306 struct ldb_dn *tmp_dn; 307 struct dom_sid *tmp_sid; 308 TALLOC_CTX *tmp_ctx; 309 struct ldb_message **res; 310 NTSTATUS status; 311 312 if (*res_sids == NULL) { 313 *num_res_sids = 0; 314 } 315 316 if (sid == NULL) { 317 return NT_STATUS_OK; 318 } 319 320 already_there = sids_contains_sid((const struct dom_sid**) *res_sids, 321 *num_res_sids, sid); 322 if (already_there) { 323 return NT_STATUS_OK; 324 } 325 326 if (!only_childs) { 327 tmp_sid = dom_sid_dup(res_sids_ctx, sid); 328 NT_STATUS_HAVE_NO_MEMORY(tmp_sid); 329 *res_sids = talloc_realloc(res_sids_ctx, *res_sids, 330 struct dom_sid *, *num_res_sids + 1); 331 NT_STATUS_HAVE_NO_MEMORY(*res_sids); 332 (*res_sids)[*num_res_sids] = tmp_sid; 333 ++(*num_res_sids); 334 } 335 336 tmp_ctx = talloc_new(sam_ctx); 337 338 ret = gendb_search(sam_ctx, tmp_ctx, NULL, &res, attrs, 339 "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); 340 if (ret != 1) { 341 talloc_free(tmp_ctx); 342 return NT_STATUS_INTERNAL_DB_CORRUPTION; 343 } 344 345 if (res[0]->num_elements == 0) { 346 talloc_free(res); 347 talloc_free(tmp_ctx); 348 return NT_STATUS_OK; 349 } 350 351 for (i = 0; i < res[0]->elements[0].num_values; i++) { 352 tmp_dn = ldb_dn_from_ldb_val(tmp_ctx, sam_ctx, 353 &res[0]->elements[0].values[i]); 354 tmp_sid = samdb_search_dom_sid(sam_ctx, tmp_ctx, tmp_dn, 355 "objectSid", NULL); 356 357 status = authsam_expand_nested_groups(sam_ctx, tmp_sid, 358 false, res_sids_ctx, res_sids, num_res_sids); 359 if (!NT_STATUS_IS_OK(status)) { 360 talloc_free(res); 361 talloc_free(tmp_ctx); 362 return status; 363 } 364 } 365 366 talloc_free(res); 367 talloc_free(tmp_ctx); 368 369 return NT_STATUS_OK; 370 } 371 372 _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, 270 _PUBLIC_ NTSTATUS authsam_make_user_info_dc(TALLOC_CTX *mem_ctx, 373 271 struct ldb_context *sam_ctx, 374 272 const char *netbios_name, … … 378 276 DATA_BLOB user_sess_key, 379 277 DATA_BLOB lm_sess_key, 380 struct auth_serversupplied_info 381 **_server_info) 278 struct auth_user_info_dc **_user_info_dc) 382 279 { 383 280 NTSTATUS status; 384 struct auth_ serversupplied_info *server_info;385 const char *str;386 struct dom_sid *tmp_sid;281 struct auth_user_info_dc *user_info_dc; 282 struct auth_user_info *info; 283 const char *str, *filter; 387 284 /* SIDs for the account and his primary group */ 388 285 struct dom_sid *account_sid; 389 struct dom_sid *primary_group_sid; 286 const char *primary_group_string; 287 const char *primary_group_dn; 288 DATA_BLOB primary_group_blob; 390 289 /* SID structures for the expanded group memberships */ 391 struct dom_sid **groupSIDs = NULL, **groupSIDs_2 = NULL; 392 int num_groupSIDs = 0, num_groupSIDs_2 = 0, i; 393 uint32_t userAccountControl; 394 395 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 396 NT_STATUS_HAVE_NO_MEMORY(server_info); 397 398 account_sid = samdb_result_dom_sid(server_info, msg, "objectSid"); 399 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, server_info); 400 401 primary_group_sid = dom_sid_add_rid(server_info, 402 samdb_domain_sid(sam_ctx), 403 samdb_result_uint(msg, "primaryGroupID", ~0)); 404 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_sid, server_info); 405 406 /* Expands the primary group */ 407 status = authsam_expand_nested_groups(sam_ctx, primary_group_sid, false, 408 server_info, &groupSIDs, &num_groupSIDs); 290 struct dom_sid *sids = NULL; 291 unsigned int num_sids = 0, i; 292 struct dom_sid *domain_sid; 293 TALLOC_CTX *tmp_ctx; 294 struct ldb_message_element *el; 295 296 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 297 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 298 299 tmp_ctx = talloc_new(user_info_dc); 300 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc, user_info_dc); 301 302 sids = talloc_array(user_info_dc, struct dom_sid, 2); 303 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, user_info_dc); 304 305 num_sids = 2; 306 307 account_sid = samdb_result_dom_sid(user_info_dc, msg, "objectSid"); 308 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(account_sid, user_info_dc); 309 310 status = dom_sid_split_rid(tmp_ctx, account_sid, &domain_sid, NULL); 409 311 if (!NT_STATUS_IS_OK(status)) { 410 talloc_free( server_info);312 talloc_free(user_info_dc); 411 313 return status; 412 314 } 413 315 316 sids[PRIMARY_USER_SID_INDEX] = *account_sid; 317 sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; 318 sid_append_rid(&sids[PRIMARY_GROUP_SID_INDEX], ldb_msg_find_attr_as_uint(msg, "primaryGroupID", ~0)); 319 320 /* Filter out builtin groups from this token. We will search 321 * for builtin groups later, and not include them in the PAC 322 * on SamLogon validation info */ 323 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(!(groupType:1.2.840.113556.1.4.803:=%u))(groupType:1.2.840.113556.1.4.803:=%u))", GROUP_TYPE_BUILTIN_LOCAL_GROUP, GROUP_TYPE_SECURITY_ENABLED); 324 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(filter, user_info_dc); 325 326 primary_group_string = dom_sid_string(tmp_ctx, &sids[PRIMARY_GROUP_SID_INDEX]); 327 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_string, user_info_dc); 328 329 primary_group_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", primary_group_string); 330 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(primary_group_dn, user_info_dc); 331 332 primary_group_blob = data_blob_string_const(primary_group_dn); 333 334 /* Expands the primary group - this function takes in 335 * memberOf-like values, so we fake one up with the 336 * <SID=S-...> format of DN and then let it expand 337 * them, as long as they meet the filter - so only 338 * domain groups, not builtin groups 339 * 340 * The primary group is still treated specially, so we set the 341 * 'only childs' flag to true 342 */ 343 status = dsdb_expand_nested_groups(sam_ctx, &primary_group_blob, true, filter, 344 user_info_dc, &sids, &num_sids); 345 if (!NT_STATUS_IS_OK(status)) { 346 talloc_free(user_info_dc); 347 return status; 348 } 349 414 350 /* Expands the additional groups */ 415 status = authsam_expand_nested_groups(sam_ctx, account_sid, true, 416 server_info, &groupSIDs_2, &num_groupSIDs_2); 417 if (!NT_STATUS_IS_OK(status)) { 418 talloc_free(server_info); 419 return status; 420 } 421 422 /* Merge the two expanded structures (groupSIDs, groupSIDs_2) */ 423 for (i = 0; i < num_groupSIDs_2; i++) 424 if (!sids_contains_sid((const struct dom_sid **) groupSIDs, 425 num_groupSIDs, groupSIDs_2[i])) { 426 tmp_sid = dom_sid_dup(server_info, groupSIDs_2[i]); 427 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(tmp_sid, server_info); 428 groupSIDs = talloc_realloc(server_info, groupSIDs, 429 struct dom_sid *, num_groupSIDs + 1); 430 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs, 431 server_info); 432 groupSIDs[num_groupSIDs] = tmp_sid; 433 ++num_groupSIDs; 434 } 435 talloc_free(groupSIDs_2); 436 437 server_info->account_sid = account_sid; 438 server_info->primary_group_sid = primary_group_sid; 439 440 /* DCs also get SID_NT_ENTERPRISE_DCS */ 441 userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0); 442 if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) { 443 groupSIDs = talloc_realloc(server_info, groupSIDs, struct dom_sid *, 444 num_groupSIDs+1); 445 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs, server_info); 446 groupSIDs[num_groupSIDs] = dom_sid_parse_talloc(groupSIDs, SID_NT_ENTERPRISE_DCS); 447 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupSIDs[num_groupSIDs], server_info); 448 num_groupSIDs++; 449 } 450 451 server_info->domain_groups = groupSIDs; 452 server_info->n_domain_groups = num_groupSIDs; 453 454 server_info->account_name = talloc_steal(server_info, 455 samdb_result_string(msg, "sAMAccountName", NULL)); 456 457 server_info->domain_name = talloc_strdup(server_info, domain_name); 458 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->domain_name, 459 server_info); 460 461 str = samdb_result_string(msg, "displayName", ""); 462 server_info->full_name = talloc_strdup(server_info, str); 463 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->full_name, server_info); 464 465 str = samdb_result_string(msg, "scriptPath", ""); 466 server_info->logon_script = talloc_strdup(server_info, str); 467 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_script, 468 server_info); 469 470 str = samdb_result_string(msg, "profilePath", ""); 471 server_info->profile_path = talloc_strdup(server_info, str); 472 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->profile_path, 473 server_info); 474 475 str = samdb_result_string(msg, "homeDirectory", ""); 476 server_info->home_directory = talloc_strdup(server_info, str); 477 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_directory, 478 server_info); 479 480 str = samdb_result_string(msg, "homeDrive", ""); 481 server_info->home_drive = talloc_strdup(server_info, str); 482 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->home_drive, server_info); 483 484 server_info->logon_server = talloc_strdup(server_info, netbios_name); 485 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(server_info->logon_server, 486 server_info); 487 488 server_info->last_logon = samdb_result_nttime(msg, "lastLogon", 0); 489 server_info->last_logoff = samdb_result_last_logoff(msg); 490 server_info->acct_expiry = samdb_result_account_expires(msg); 491 server_info->last_password_change = samdb_result_nttime(msg, 351 el = ldb_msg_find_element(msg, "memberOf"); 352 for (i = 0; el && i < el->num_values; i++) { 353 /* This function takes in memberOf values and expands 354 * them, as long as they meet the filter - so only 355 * domain groups, not builtin groups */ 356 status = dsdb_expand_nested_groups(sam_ctx, &el->values[i], false, filter, 357 user_info_dc, &sids, &num_sids); 358 if (!NT_STATUS_IS_OK(status)) { 359 talloc_free(user_info_dc); 360 return status; 361 } 362 } 363 364 user_info_dc->sids = sids; 365 user_info_dc->num_sids = num_sids; 366 367 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 368 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 369 370 info->account_name = talloc_steal(info, 371 ldb_msg_find_attr_as_string(msg, "sAMAccountName", NULL)); 372 373 info->domain_name = talloc_strdup(info, domain_name); 374 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->domain_name, 375 user_info_dc); 376 377 str = ldb_msg_find_attr_as_string(msg, "displayName", ""); 378 info->full_name = talloc_strdup(info, str); 379 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->full_name, user_info_dc); 380 381 str = ldb_msg_find_attr_as_string(msg, "scriptPath", ""); 382 info->logon_script = talloc_strdup(info, str); 383 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_script, 384 user_info_dc); 385 386 str = ldb_msg_find_attr_as_string(msg, "profilePath", ""); 387 info->profile_path = talloc_strdup(info, str); 388 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->profile_path, 389 user_info_dc); 390 391 str = ldb_msg_find_attr_as_string(msg, "homeDirectory", ""); 392 info->home_directory = talloc_strdup(info, str); 393 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_directory, 394 user_info_dc); 395 396 str = ldb_msg_find_attr_as_string(msg, "homeDrive", ""); 397 info->home_drive = talloc_strdup(info, str); 398 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->home_drive, user_info_dc); 399 400 info->logon_server = talloc_strdup(info, netbios_name); 401 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(info->logon_server, 402 user_info_dc); 403 404 info->last_logon = samdb_result_nttime(msg, "lastLogon", 0); 405 info->last_logoff = samdb_result_last_logoff(msg); 406 info->acct_expiry = samdb_result_account_expires(msg); 407 info->last_password_change = samdb_result_nttime(msg, 492 408 "pwdLastSet", 0); 493 server_info->allow_password_change409 info->allow_password_change 494 410 = samdb_result_allow_password_change(sam_ctx, mem_ctx, 495 411 domain_dn, msg, "pwdLastSet"); 496 server_info->force_password_change412 info->force_password_change 497 413 = samdb_result_force_password_change(sam_ctx, mem_ctx, 498 414 domain_dn, msg); 499 server_info->logon_count = samdb_result_uint(msg, "logonCount", 0);500 server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount",415 info->logon_count = ldb_msg_find_attr_as_uint(msg, "logonCount", 0); 416 info->bad_password_count = ldb_msg_find_attr_as_uint(msg, "badPwdCount", 501 417 0); 502 418 503 server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx,419 info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, 504 420 msg, domain_dn); 505 421 506 server_info->user_session_key = data_blob_talloc_reference(server_info, 507 &user_sess_key); 508 server_info->lm_session_key = data_blob_talloc_reference(server_info, 509 &lm_sess_key); 510 511 server_info->authenticated = true; 512 513 *_server_info = server_info; 422 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, 423 user_sess_key.data, 424 user_sess_key.length); 425 if (user_sess_key.data) { 426 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->user_session_key.data, 427 user_info_dc); 428 } 429 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, 430 lm_sess_key.data, 431 lm_sess_key.length); 432 if (lm_sess_key.data) { 433 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->lm_session_key.data, 434 user_info_dc); 435 } 436 437 if (info->acct_flags & ACB_SVRTRUST) { 438 /* the SID_NT_ENTERPRISE_DCS SID gets added into the 439 PAC */ 440 user_info_dc->sids = talloc_realloc(user_info_dc, 441 user_info_dc->sids, 442 struct dom_sid, 443 user_info_dc->num_sids+1); 444 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc); 445 user_info_dc->sids[user_info_dc->num_sids] = global_sid_Enterprise_DCs; 446 user_info_dc->num_sids++; 447 } 448 449 if ((info->acct_flags & (ACB_PARTIAL_SECRETS_ACCOUNT | ACB_WSTRUST)) == 450 (ACB_PARTIAL_SECRETS_ACCOUNT | ACB_WSTRUST)) { 451 /* the DOMAIN_RID_ENTERPRISE_READONLY_DCS PAC */ 452 user_info_dc->sids = talloc_realloc(user_info_dc, 453 user_info_dc->sids, 454 struct dom_sid, 455 user_info_dc->num_sids+1); 456 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(user_info_dc->sids, user_info_dc); 457 user_info_dc->sids[user_info_dc->num_sids] = *domain_sid; 458 sid_append_rid(&user_info_dc->sids[user_info_dc->num_sids], 459 DOMAIN_RID_ENTERPRISE_READONLY_DCS); 460 user_info_dc->num_sids++; 461 } 462 463 info->authenticated = true; 464 465 talloc_free(tmp_ctx); 466 *_user_info_dc = user_info_dc; 514 467 515 468 return NT_STATUS_OK; … … 539 492 540 493 /* pull the user attributes */ 541 ret = gendb_search_single_extended_dn(sam_ctx, tmp_ctx, user_dn,542 LDB_SCOPE_BASE, msg, attrs, "(objectClass=*)");494 ret = dsdb_search_one(sam_ctx, tmp_ctx, msg, user_dn, 495 LDB_SCOPE_BASE, attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)"); 543 496 if (ret != LDB_SUCCESS) { 544 497 talloc_free(tmp_ctx); … … 551 504 return NT_STATUS_OK; 552 505 } 506 507 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available, and for tokenGroups in the DSDB stack. 508 509 Supply either a principal or a DN 510 */ 511 NTSTATUS authsam_get_user_info_dc_principal(TALLOC_CTX *mem_ctx, 512 struct loadparm_context *lp_ctx, 513 struct ldb_context *sam_ctx, 514 const char *principal, 515 struct ldb_dn *user_dn, 516 struct auth_user_info_dc **user_info_dc) 517 { 518 NTSTATUS nt_status; 519 DATA_BLOB user_sess_key = data_blob(NULL, 0); 520 DATA_BLOB lm_sess_key = data_blob(NULL, 0); 521 522 struct ldb_message *msg; 523 struct ldb_dn *domain_dn; 524 525 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 526 if (!tmp_ctx) { 527 return NT_STATUS_NO_MEMORY; 528 } 529 530 if (principal) { 531 nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal, 532 user_attrs, &domain_dn, &msg); 533 if (!NT_STATUS_IS_OK(nt_status)) { 534 talloc_free(tmp_ctx); 535 return nt_status; 536 } 537 } else if (user_dn) { 538 struct dom_sid *user_sid, *domain_sid; 539 int ret; 540 /* pull the user attributes */ 541 ret = dsdb_search_one(sam_ctx, tmp_ctx, &msg, user_dn, 542 LDB_SCOPE_BASE, user_attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)"); 543 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 544 talloc_free(tmp_ctx); 545 return NT_STATUS_NO_SUCH_USER; 546 } else if (ret != LDB_SUCCESS) { 547 talloc_free(tmp_ctx); 548 return NT_STATUS_INTERNAL_DB_CORRUPTION; 549 } 550 551 user_sid = samdb_result_dom_sid(msg, msg, "objectSid"); 552 553 nt_status = dom_sid_split_rid(tmp_ctx, user_sid, &domain_sid, NULL); 554 if (!NT_STATUS_IS_OK(nt_status)) { 555 return nt_status; 556 } 557 558 domain_dn = samdb_search_dn(sam_ctx, mem_ctx, NULL, 559 "(&(objectSid=%s)(objectClass=domain))", 560 ldap_encode_ndr_dom_sid(tmp_ctx, domain_sid)); 561 if (!domain_dn) { 562 DEBUG(3, ("authsam_get_user_info_dc_principal: Failed to find domain with: SID %s\n", 563 dom_sid_string(tmp_ctx, domain_sid))); 564 return NT_STATUS_NO_SUCH_USER; 565 } 566 567 } else { 568 return NT_STATUS_INVALID_PARAMETER; 569 } 570 571 nt_status = authsam_make_user_info_dc(tmp_ctx, sam_ctx, 572 lpcfg_netbios_name(lp_ctx), 573 lpcfg_workgroup(lp_ctx), 574 domain_dn, 575 msg, 576 user_sess_key, lm_sess_key, 577 user_info_dc); 578 if (!NT_STATUS_IS_OK(nt_status)) { 579 talloc_free(tmp_ctx); 580 return nt_status; 581 } 582 583 talloc_steal(mem_ctx, *user_info_dc); 584 talloc_free(tmp_ctx); 585 586 return NT_STATUS_OK; 587 } -
vendor/current/source4/auth/samba_server_gensec.c
r414 r740 39 39 struct gensec_security *gensec_ctx; 40 40 struct auth_context *auth_context; 41 42 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 43 if (!tmp_ctx) { 44 return NT_STATUS_NO_MEMORY; 45 } 41 46 42 nt_status = auth_context_create( mem_ctx,47 nt_status = auth_context_create(tmp_ctx, 43 48 event_ctx, 44 49 msg_ctx, … … 48 53 if (!NT_STATUS_IS_OK(nt_status)) { 49 54 DEBUG(1, ("Failed to start auth server code: %s\n", nt_errstr(nt_status))); 55 talloc_free(tmp_ctx); 50 56 return nt_status; 51 57 } 52 58 53 nt_status = gensec_server_start( mem_ctx,59 nt_status = gensec_server_start(tmp_ctx, 54 60 event_ctx, 55 lp _gensec_settings(mem_ctx, lp_ctx),61 lpcfg_gensec_settings(mem_ctx, lp_ctx), 56 62 auth_context, 57 63 &gensec_ctx); 58 64 if (!NT_STATUS_IS_OK(nt_status)) { 59 talloc_free( auth_context);65 talloc_free(tmp_ctx); 60 66 DEBUG(1, ("Failed to start GENSEC server code: %s\n", nt_errstr(nt_status))); 61 67 return nt_status; … … 67 73 gensec_set_target_service(gensec_ctx, target_service); 68 74 } 69 *gensec_context = gensec_ctx; 75 *gensec_context = talloc_steal(mem_ctx, gensec_ctx); 76 talloc_free(tmp_ctx); 70 77 return nt_status; 71 78 } -
vendor/current/source4/auth/session.c
r414 r740 3 3 Authentication utility functions 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 Copyright (C) Andrew Bartlett 2001 5 Copyright (C) Andrew Bartlett 2001-2010 6 6 Copyright (C) Jeremy Allison 2000-2001 7 7 Copyright (C) Rafal Szczesniak 2002 … … 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "auth/auth_sam.h" 27 #include "auth/credentials/credentials.h" 28 #include "auth/credentials/credentials_krb5.h" 26 29 #include "libcli/security/security.h" 27 30 #include "libcli/auth/libcli_auth.h" 28 31 #include "dsdb/samdb/samdb.h" 29 #include "auth/credentials/credentials.h"30 #include "param/param.h"31 32 #include "auth/session_proto.h" 33 #include "system/kerberos.h" 34 #include <gssapi/gssapi.h> 32 35 33 36 _PUBLIC_ struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, 34 struct tevent_context *event_ctx, 35 struct loadparm_context *lp_ctx) 37 struct loadparm_context *lp_ctx) 36 38 { 37 39 NTSTATUS nt_status; 38 40 struct auth_session_info *session_info = NULL; 39 nt_status = auth_anonymous_session_info(mem_ctx, event_ctx,lp_ctx, &session_info);41 nt_status = auth_anonymous_session_info(mem_ctx, lp_ctx, &session_info); 40 42 if (!NT_STATUS_IS_OK(nt_status)) { 41 43 return NULL; … … 44 46 } 45 47 46 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 47 struct tevent_context *event_ctx, 48 struct loadparm_context *lp_ctx, 49 struct auth_session_info **_session_info) 50 { 51 NTSTATUS nt_status; 52 struct auth_serversupplied_info *server_info = NULL; 53 struct auth_session_info *session_info = NULL; 54 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 55 56 nt_status = auth_anonymous_server_info(mem_ctx, 57 lp_netbios_name(lp_ctx), 58 &server_info); 59 if (!NT_STATUS_IS_OK(nt_status)) { 60 talloc_free(mem_ctx); 61 return nt_status; 62 } 63 64 /* references the server_info into the session_info */ 65 nt_status = auth_generate_session_info(parent_ctx, event_ctx, lp_ctx, server_info, &session_info); 66 talloc_free(mem_ctx); 67 68 NT_STATUS_NOT_OK_RETURN(nt_status); 69 70 session_info->credentials = cli_credentials_init(session_info); 71 if (!session_info->credentials) { 72 return NT_STATUS_NO_MEMORY; 73 } 74 75 cli_credentials_set_conf(session_info->credentials, lp_ctx); 76 cli_credentials_set_anonymous(session_info->credentials); 77 78 *_session_info = session_info; 79 80 return NT_STATUS_OK; 81 } 82 83 _PUBLIC_ NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx, 84 const char *netbios_name, 85 struct auth_serversupplied_info **_server_info) 86 { 87 struct auth_serversupplied_info *server_info; 88 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 89 NT_STATUS_HAVE_NO_MEMORY(server_info); 90 91 server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS); 92 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 93 94 /* is this correct? */ 95 server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS); 96 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 97 98 server_info->n_domain_groups = 0; 99 server_info->domain_groups = NULL; 100 101 /* annoying, but the Anonymous really does have a session key... */ 102 server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); 103 NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); 104 105 server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); 106 NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); 107 108 /* and it is all zeros! */ 109 data_blob_clear(&server_info->user_session_key); 110 data_blob_clear(&server_info->lm_session_key); 111 112 server_info->account_name = talloc_strdup(server_info, "ANONYMOUS LOGON"); 113 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 114 115 server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY"); 116 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 117 118 server_info->full_name = talloc_strdup(server_info, "Anonymous Logon"); 119 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 120 121 server_info->logon_script = talloc_strdup(server_info, ""); 122 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 123 124 server_info->profile_path = talloc_strdup(server_info, ""); 125 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 126 127 server_info->home_directory = talloc_strdup(server_info, ""); 128 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 129 130 server_info->home_drive = talloc_strdup(server_info, ""); 131 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 132 133 server_info->logon_server = talloc_strdup(server_info, netbios_name); 134 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); 135 136 server_info->last_logon = 0; 137 server_info->last_logoff = 0; 138 server_info->acct_expiry = 0; 139 server_info->last_password_change = 0; 140 server_info->allow_password_change = 0; 141 server_info->force_password_change = 0; 142 143 server_info->logon_count = 0; 144 server_info->bad_password_count = 0; 145 146 server_info->acct_flags = ACB_NORMAL; 147 148 server_info->authenticated = false; 149 150 *_server_info = server_info; 151 152 return NT_STATUS_OK; 153 } 154 155 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 156 struct tevent_context *event_ctx, 157 struct loadparm_context *lp_ctx, 158 struct auth_serversupplied_info *server_info, 159 struct auth_session_info **_session_info) 48 _PUBLIC_ NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 49 struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */ 50 struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */ 51 struct auth_user_info_dc *user_info_dc, 52 uint32_t session_info_flags, 53 struct auth_session_info **_session_info) 160 54 { 161 55 struct auth_session_info *session_info; 162 56 NTSTATUS nt_status; 163 164 session_info = talloc(mem_ctx, struct auth_session_info); 165 NT_STATUS_HAVE_NO_MEMORY(session_info); 166 167 session_info->server_info = talloc_reference(session_info, server_info); 57 unsigned int i, num_sids = 0; 58 59 const char *filter; 60 61 struct dom_sid *sids = NULL; 62 const struct dom_sid *anonymous_sid, *system_sid; 63 64 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 65 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); 66 67 session_info = talloc(tmp_ctx, struct auth_session_info); 68 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info, tmp_ctx); 69 70 session_info->info = talloc_reference(session_info, user_info_dc->info); 71 72 session_info->torture = talloc_zero(session_info, struct auth_user_info_torture); 73 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture, tmp_ctx); 74 session_info->torture->num_dc_sids = user_info_dc->num_sids; 75 session_info->torture->dc_sids = talloc_reference(session_info, user_info_dc->sids); 76 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->torture->dc_sids, tmp_ctx); 168 77 169 78 /* unless set otherwise, the session key is the user session 170 79 * key from the auth subsystem */ 171 session_info->session_key = server_info->user_session_key; 80 session_info->session_key = data_blob_talloc(session_info, user_info_dc->user_session_key.data, user_info_dc->user_session_key.length); 81 if (!session_info->session_key.data && session_info->session_key.length) { 82 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(session_info->session_key.data, tmp_ctx); 83 } 84 85 anonymous_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_ANONYMOUS); 86 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(anonymous_sid, tmp_ctx); 87 88 system_sid = dom_sid_parse_talloc(tmp_ctx, SID_NT_SYSTEM); 89 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(system_sid, tmp_ctx); 90 91 sids = talloc_array(tmp_ctx, struct dom_sid, user_info_dc->num_sids); 92 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sids, tmp_ctx); 93 if (!sids) { 94 talloc_free(tmp_ctx); 95 return NT_STATUS_NO_MEMORY; 96 } 97 98 num_sids = user_info_dc->num_sids; 99 100 for (i=0; i < user_info_dc->num_sids; i++) { 101 sids[i] = user_info_dc->sids[i]; 102 } 103 104 if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(anonymous_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) { 105 /* Don't expand nested groups of system, anonymous etc*/ 106 } else if (user_info_dc->num_sids > PRIMARY_USER_SID_INDEX && dom_sid_equal(system_sid, &user_info_dc->sids[PRIMARY_USER_SID_INDEX])) { 107 /* Don't expand nested groups of system, anonymous etc*/ 108 } else if (sam_ctx) { 109 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))", 110 GROUP_TYPE_BUILTIN_LOCAL_GROUP); 111 112 /* Search for each group in the token */ 113 for (i = 0; i < user_info_dc->num_sids; i++) { 114 char *sid_string; 115 const char *sid_dn; 116 DATA_BLOB sid_blob; 117 118 sid_string = dom_sid_string(tmp_ctx, 119 &user_info_dc->sids[i]); 120 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, user_info_dc); 121 122 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string); 123 talloc_free(sid_string); 124 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, user_info_dc); 125 sid_blob = data_blob_string_const(sid_dn); 126 127 /* This function takes in memberOf values and expands 128 * them, as long as they meet the filter - so only 129 * builtin groups 130 * 131 * We already have the SID in the token, so set 132 * 'only childs' flag to true */ 133 nt_status = dsdb_expand_nested_groups(sam_ctx, &sid_blob, true, filter, 134 tmp_ctx, &sids, &num_sids); 135 if (!NT_STATUS_IS_OK(nt_status)) { 136 talloc_free(tmp_ctx); 137 return nt_status; 138 } 139 } 140 } 172 141 173 142 nt_status = security_token_create(session_info, 174 event_ctx,175 143 lp_ctx, 176 server_info->account_sid, 177 server_info->primary_group_sid, 178 server_info->n_domain_groups, 179 server_info->domain_groups, 180 server_info->authenticated, 144 num_sids, 145 sids, 146 session_info_flags, 181 147 &session_info->security_token); 182 NT_STATUS_NOT_OK_RETURN (nt_status);148 NT_STATUS_NOT_OK_RETURN_AND_FREE(nt_status, tmp_ctx); 183 149 184 150 session_info->credentials = NULL; 185 151 152 talloc_steal(mem_ctx, session_info); 186 153 *_session_info = session_info; 154 talloc_free(tmp_ctx); 187 155 return NT_STATUS_OK; 156 } 157 158 /* Create a session_info structure from the 159 * auth_session_info_transport we were forwarded over named pipe 160 * forwarding. 161 * 162 * NOTE: The stucture members of session_info_transport are stolen 163 * with talloc_move() into auth_session_info for long term use 164 */ 165 struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx, 166 struct auth_session_info_transport *session_info_transport, 167 struct loadparm_context *lp_ctx, 168 const char **reason) 169 { 170 struct auth_session_info *session_info; 171 session_info = talloc_zero(mem_ctx, struct auth_session_info); 172 if (!session_info) { 173 *reason = "failed to allocate session_info"; 174 return NULL; 175 } 176 177 session_info->security_token = talloc_move(session_info, &session_info_transport->security_token); 178 session_info->info = talloc_move(session_info, &session_info_transport->info); 179 session_info->session_key = session_info_transport->session_key; 180 session_info->session_key.data = talloc_move(session_info, &session_info_transport->session_key.data); 181 182 if (session_info_transport->exported_gssapi_credentials.length) { 183 struct cli_credentials *creds; 184 OM_uint32 minor_status; 185 gss_buffer_desc cred_token; 186 gss_cred_id_t cred_handle; 187 const char *error_string; 188 int ret; 189 190 DEBUG(10, ("Delegated credentials supplied by client\n")); 191 192 cred_token.value = session_info_transport->exported_gssapi_credentials.data; 193 cred_token.length = session_info_transport->exported_gssapi_credentials.length; 194 195 ret = gss_import_cred(&minor_status, 196 &cred_token, 197 &cred_handle); 198 if (ret != GSS_S_COMPLETE) { 199 *reason = "Internal error in gss_import_cred()"; 200 return NULL; 201 } 202 203 creds = cli_credentials_init(session_info); 204 if (!creds) { 205 *reason = "Out of memory in cli_credentials_init()"; 206 return NULL; 207 } 208 session_info->credentials = creds; 209 210 cli_credentials_set_conf(creds, lp_ctx); 211 /* Just so we don't segfault trying to get at a username */ 212 cli_credentials_set_anonymous(creds); 213 214 ret = cli_credentials_set_client_gss_creds(creds, 215 lp_ctx, 216 cred_handle, 217 CRED_SPECIFIED, 218 &error_string); 219 if (ret) { 220 *reason = talloc_asprintf(mem_ctx, 221 "Failed to set pipe forwarded" 222 "creds: %s\n", error_string); 223 return NULL; 224 } 225 226 /* This credential handle isn't useful for password 227 * authentication, so ensure nobody tries to do that */ 228 cli_credentials_set_kerberos_state(creds, 229 CRED_MUST_USE_KERBEROS); 230 231 } 232 233 return session_info; 234 } 235 236 237 /* Create a auth_session_info_transport from an auth_session_info. 238 * 239 * NOTE: Members of the auth_session_info_transport structure are not talloc_referenced, but simply assigned. They are only valid for the lifetime of the struct auth_session_info 240 * 241 * This isn't normally an issue, as the auth_session_info has a very long typical life 242 */ 243 NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx, 244 struct auth_session_info *session_info, 245 struct tevent_context *event_ctx, 246 struct loadparm_context *lp_ctx, 247 struct auth_session_info_transport **transport_out) 248 { 249 250 struct auth_session_info_transport *session_info_transport = talloc_zero(mem_ctx, struct auth_session_info_transport); 251 session_info_transport->security_token = talloc_reference(session_info, session_info->security_token); 252 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->security_token); 253 254 session_info_transport->info = talloc_reference(session_info, session_info->info); 255 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->info); 256 257 session_info_transport->session_key = session_info->session_key; 258 session_info_transport->session_key.data = talloc_reference(session_info, session_info->session_key.data); 259 if (!session_info_transport->session_key.data && session_info->session_key.length) { 260 return NT_STATUS_NO_MEMORY; 261 } 262 263 if (session_info->credentials) { 264 struct gssapi_creds_container *gcc; 265 OM_uint32 gret; 266 OM_uint32 minor_status; 267 gss_buffer_desc cred_token; 268 const char *error_string; 269 int ret; 270 271 ret = cli_credentials_get_client_gss_creds(session_info->credentials, 272 event_ctx, 273 lp_ctx, 274 &gcc, &error_string); 275 if (ret != 0) { 276 *transport_out = session_info_transport; 277 return NT_STATUS_OK; 278 } 279 280 gret = gss_export_cred(&minor_status, 281 gcc->creds, 282 &cred_token); 283 if (gret != GSS_S_COMPLETE) { 284 return NT_STATUS_INTERNAL_ERROR; 285 } 286 287 if (cred_token.length) { 288 session_info_transport->exported_gssapi_credentials 289 = data_blob_talloc(session_info_transport, 290 cred_token.value, 291 cred_token.length); 292 gss_release_buffer(&minor_status, &cred_token); 293 NT_STATUS_HAVE_NO_MEMORY(session_info_transport->exported_gssapi_credentials.data); 294 } 295 } 296 *transport_out = session_info_transport; 297 return NT_STATUS_OK; 298 } 299 300 301 /* Produce a session_info for an arbitary DN or principal in the local 302 * DB, assuming the local DB holds all the groups 303 * 304 * Supply either a principal or a DN 305 */ 306 NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx, 307 struct loadparm_context *lp_ctx, 308 struct ldb_context *sam_ctx, 309 const char *principal, 310 struct ldb_dn *user_dn, 311 uint32_t session_info_flags, 312 struct auth_session_info **session_info) 313 { 314 NTSTATUS nt_status; 315 struct auth_user_info_dc *user_info_dc; 316 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 317 if (!tmp_ctx) { 318 return NT_STATUS_NO_MEMORY; 319 } 320 nt_status = authsam_get_user_info_dc_principal(tmp_ctx, lp_ctx, sam_ctx, 321 principal, user_dn, 322 &user_info_dc); 323 if (!NT_STATUS_IS_OK(nt_status)) { 324 talloc_free(tmp_ctx); 325 return nt_status; 326 } 327 328 nt_status = auth_generate_session_info(tmp_ctx, lp_ctx, sam_ctx, 329 user_info_dc, session_info_flags, 330 session_info); 331 332 if (NT_STATUS_IS_OK(nt_status)) { 333 talloc_steal(mem_ctx, *session_info); 334 } 335 talloc_free(tmp_ctx); 336 return nt_status; 188 337 } 189 338 … … 199 348 } 200 349 201 security_token_debug( dbg_lev, session_info->security_token);202 } 203 350 security_token_debug(0, dbg_lev, session_info->security_token); 351 } 352 -
vendor/current/source4/auth/session.h
r414 r740 22 22 #define _SAMBA_AUTH_SESSION_H 23 23 24 struct auth_session_info { 25 struct security_token *security_token; 26 struct auth_serversupplied_info *server_info; 27 DATA_BLOB session_key; 28 struct cli_credentials *credentials; 29 }; 30 24 #include "librpc/gen_ndr/security.h" 31 25 #include "librpc/gen_ndr/netlogon.h" 26 #include "librpc/gen_ndr/auth.h" 32 27 33 28 struct tevent_context; 34 29 struct ldb_context; 30 struct ldb_dn; 35 31 /* Create a security token for a session SYSTEM (the most 36 32 * trusted/prvilaged account), including the local machine account as 37 33 * the off-host credentials */ 38 struct auth_session_info *system_session( TALLOC_CTX *mem_ctx,struct loadparm_context *lp_ctx) ;34 struct auth_session_info *system_session(struct loadparm_context *lp_ctx) ; 39 35 40 /* 41 * Create a system session, but with anonymous credentials (so we do 42 * not need to open secrets.ldb) 36 NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx, 37 const char *netbios_name, 38 struct auth_user_info_dc **interim_info); 39 NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 40 struct loadparm_context *lp_ctx, /* Optional, if you don't want privilages */ 41 struct ldb_context *sam_ctx, /* Optional, if you don't want local groups */ 42 struct auth_user_info_dc *interim_info, 43 uint32_t session_info_flags, 44 struct auth_session_info **session_info); 45 NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 46 struct loadparm_context *lp_ctx, 47 struct auth_session_info **session_info); 48 struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx, 49 struct auth_session_info_transport *session_info_transport, 50 struct loadparm_context *lp_ctx, 51 const char **reason); 52 NTSTATUS auth_session_info_transport_from_session(TALLOC_CTX *mem_ctx, 53 struct auth_session_info *session_info, 54 struct tevent_context *event_ctx, 55 struct loadparm_context *lp_ctx, 56 struct auth_session_info_transport **transport_out); 57 58 /* Produce a session_info for an arbitary DN or principal in the local 59 * DB, assuming the local DB holds all the groups 60 * 61 * Supply either a principal or a DN 43 62 */ 44 struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); 45 46 47 NTSTATUS auth_anonymous_server_info(TALLOC_CTX *mem_ctx, 48 const char *netbios_name, 49 struct auth_serversupplied_info **_server_info) ; 50 NTSTATUS auth_generate_session_info(TALLOC_CTX *mem_ctx, 51 struct tevent_context *event_ctx, 52 struct loadparm_context *lp_ctx, 53 struct auth_serversupplied_info *server_info, 54 struct auth_session_info **_session_info) ; 55 56 NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 57 struct tevent_context *ev_ctx, 58 struct loadparm_context *lp_ctx, 59 struct auth_session_info **_session_info); 63 NTSTATUS authsam_get_session_info_principal(TALLOC_CTX *mem_ctx, 64 struct loadparm_context *lp_ctx, 65 struct ldb_context *sam_ctx, 66 const char *principal, 67 struct ldb_dn *user_dn, 68 uint32_t session_info_flags, 69 struct auth_session_info **session_info); 60 70 61 71 struct auth_session_info *anonymous_session(TALLOC_CTX *mem_ctx, 62 struct tevent_context *event_ctx,63 72 struct loadparm_context *lp_ctx); 64 73 -
vendor/current/source4/auth/system_session.c
r414 r740 3 3 Authentication utility functions 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 Copyright (C) Andrew Bartlett 2001 5 Copyright (C) Andrew Bartlett 2001-2010 6 6 Copyright (C) Jeremy Allison 2000-2001 7 7 Copyright (C) Rafal Szczesniak 2002 … … 24 24 #include "includes.h" 25 25 #include "libcli/security/security.h" 26 #include "libcli/auth/libcli_auth.h"27 26 #include "auth/credentials/credentials.h" 28 27 #include "param/param.h" 29 #include "auth/auth.h" /* for auth_ serversupplied_info*/28 #include "auth/auth.h" /* for auth_user_info_dc */ 30 29 #include "auth/session.h" 31 30 #include "auth/system_session_proto.h" 32 31 33 /** 34 * Create the SID list for this user. 35 * 36 * @note Specialised version for system sessions that doesn't use the SAM. 32 33 /* 34 prevent the static system session being freed 37 35 */ 38 static NTSTATUS create_token(TALLOC_CTX *mem_ctx, 39 struct dom_sid *user_sid, 40 struct dom_sid *group_sid, 41 int n_groupSIDs, 42 struct dom_sid **groupSIDs, 43 bool is_authenticated, 44 struct security_token **token) 45 { 46 struct security_token *ptoken; 47 int i; 48 49 ptoken = security_token_initialise(mem_ctx); 50 NT_STATUS_HAVE_NO_MEMORY(ptoken); 51 52 ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 5); 53 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); 54 55 ptoken->user_sid = talloc_reference(ptoken, user_sid); 56 ptoken->group_sid = talloc_reference(ptoken, group_sid); 57 ptoken->privilege_mask = 0; 58 59 ptoken->sids[0] = ptoken->user_sid; 60 ptoken->sids[1] = ptoken->group_sid; 61 62 /* 63 * Finally add the "standard" SIDs. 64 * The only difference between guest and "anonymous" 65 * is the addition of Authenticated_Users. 66 */ 67 ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_WORLD); 68 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); 69 ptoken->sids[3] = dom_sid_parse_talloc(ptoken->sids, SID_NT_NETWORK); 70 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[3]); 71 ptoken->num_sids = 4; 72 73 if (is_authenticated) { 74 ptoken->sids[4] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); 75 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[4]); 76 ptoken->num_sids++; 77 } 78 79 for (i = 0; i < n_groupSIDs; i++) { 80 size_t check_sid_idx; 81 for (check_sid_idx = 1; 82 check_sid_idx < ptoken->num_sids; 83 check_sid_idx++) { 84 if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { 85 break; 86 } 87 } 88 89 if (check_sid_idx == ptoken->num_sids) { 90 ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); 91 } 92 } 93 94 *token = ptoken; 95 96 /* Shortcuts to prevent recursion and avoid lookups */ 97 if (ptoken->user_sid == NULL) { 98 ptoken->privilege_mask = 0; 99 return NT_STATUS_OK; 100 } 101 102 if (security_token_is_system(ptoken)) { 103 ptoken->privilege_mask = ~0; 104 return NT_STATUS_OK; 105 } 106 107 if (security_token_is_anonymous(ptoken)) { 108 ptoken->privilege_mask = 0; 109 return NT_STATUS_OK; 110 } 111 112 DEBUG(0, ("Created token was not system or anonymous token!")); 113 *token = NULL; 114 return NT_STATUS_INTERNAL_ERROR; 115 } 116 117 static NTSTATUS generate_session_info(TALLOC_CTX *mem_ctx, 118 struct auth_serversupplied_info *server_info, 119 struct auth_session_info **_session_info) 120 { 121 struct auth_session_info *session_info; 122 NTSTATUS nt_status; 123 124 session_info = talloc(mem_ctx, struct auth_session_info); 125 NT_STATUS_HAVE_NO_MEMORY(session_info); 126 127 session_info->server_info = talloc_reference(session_info, server_info); 128 129 /* unless set otherwise, the session key is the user session 130 * key from the auth subsystem */ 131 session_info->session_key = server_info->user_session_key; 132 133 nt_status = create_token(session_info, 134 server_info->account_sid, 135 server_info->primary_group_sid, 136 server_info->n_domain_groups, 137 server_info->domain_groups, 138 server_info->authenticated, 139 &session_info->security_token); 140 NT_STATUS_NOT_OK_RETURN(nt_status); 141 142 session_info->credentials = NULL; 143 144 *_session_info = session_info; 145 return NT_STATUS_OK; 146 } 147 148 36 static int system_session_destructor(struct auth_session_info *info) 37 { 38 return -1; 39 } 149 40 150 41 /* Create a security token for a session SYSTEM (the most … … 152 43 * the off-host credentials 153 44 */ 154 _PUBLIC_ struct auth_session_info *system_session(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 155 { 45 _PUBLIC_ struct auth_session_info *system_session(struct loadparm_context *lp_ctx) 46 { 47 static struct auth_session_info *static_session; 156 48 NTSTATUS nt_status; 157 struct auth_session_info *session_info = NULL; 158 nt_status = auth_system_session_info(mem_ctx, 49 50 if (static_session) { 51 return static_session; 52 } 53 54 nt_status = auth_system_session_info(talloc_autofree_context(), 159 55 lp_ctx, 160 &s ession_info);56 &static_session); 161 57 if (!NT_STATUS_IS_OK(nt_status)) { 58 talloc_free(static_session); 59 static_session = NULL; 162 60 return NULL; 163 61 } 164 return session_info;165 } 166 167 static NTSTATUS _auth_system_session_info(TALLOC_CTX *parent_ctx, 168 struct loadparm_context *lp_ctx, 169 bool anonymous_credentials,170 62 talloc_set_destructor(static_session, system_session_destructor); 63 return static_session; 64 } 65 66 NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 67 struct loadparm_context *lp_ctx, 68 struct auth_session_info **_session_info) 171 69 { 172 70 NTSTATUS nt_status; 173 struct auth_ serversupplied_info *server_info= NULL;71 struct auth_user_info_dc *user_info_dc = NULL; 174 72 struct auth_session_info *session_info = NULL; 175 73 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 176 74 177 nt_status = auth_system_ server_info(mem_ctx, lp_netbios_name(lp_ctx),178 & server_info);75 nt_status = auth_system_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), 76 &user_info_dc); 179 77 if (!NT_STATUS_IS_OK(nt_status)) { 180 78 talloc_free(mem_ctx); … … 182 80 } 183 81 184 /* references the server_infointo the session_info */185 nt_status = generate_session_info(parent_ctx, server_info, &session_info);82 /* references the user_info_dc into the session_info */ 83 nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info); 186 84 talloc_free(mem_ctx); 187 85 … … 195 93 cli_credentials_set_conf(session_info->credentials, lp_ctx); 196 94 197 if (anonymous_credentials) { 198 cli_credentials_set_anonymous(session_info->credentials); 199 } else { 200 cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx); 201 } 95 cli_credentials_set_machine_account_pending(session_info->credentials, lp_ctx); 202 96 *_session_info = session_info; 203 97 … … 205 99 } 206 100 207 /* 208 Create a system session, but with anonymous credentials (so we do not need to open secrets.ldb) 209 */ 210 _PUBLIC_ struct auth_session_info *system_session_anon(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 211 { 212 NTSTATUS nt_status; 213 struct auth_session_info *session_info = NULL; 214 nt_status = _auth_system_session_info(mem_ctx, lp_ctx, false, &session_info); 215 if (!NT_STATUS_IS_OK(nt_status)) { 216 return NULL; 217 } 218 return session_info; 219 } 220 221 222 223 _PUBLIC_ NTSTATUS auth_system_session_info(TALLOC_CTX *parent_ctx, 224 struct loadparm_context *lp_ctx, 225 struct auth_session_info **_session_info) 226 { 227 return _auth_system_session_info(parent_ctx, 228 lp_ctx, 229 lp_parm_bool(lp_ctx, NULL, "system", "anonymous", false), 230 _session_info); 231 } 232 233 NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name, 234 struct auth_serversupplied_info **_server_info) 235 { 236 struct auth_serversupplied_info *server_info; 237 238 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 239 NT_STATUS_HAVE_NO_MEMORY(server_info); 240 241 server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_SYSTEM); 242 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 243 244 /* is this correct? */ 245 server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS); 246 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 247 248 server_info->n_domain_groups = 0; 249 server_info->domain_groups = NULL; 101 NTSTATUS auth_system_user_info_dc(TALLOC_CTX *mem_ctx, const char *netbios_name, 102 struct auth_user_info_dc **_user_info_dc) 103 { 104 struct auth_user_info_dc *user_info_dc; 105 struct auth_user_info *info; 106 107 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 108 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 109 110 /* This returns a pointer to a struct dom_sid, which is the 111 * same as a 1 element list of struct dom_sid */ 112 user_info_dc->num_sids = 1; 113 user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_SYSTEM); 114 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); 250 115 251 116 /* annoying, but the Anonymous really does have a session key, 252 117 and it is all zeros! */ 253 server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); 254 NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); 255 256 server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); 257 NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); 258 259 data_blob_clear(&server_info->user_session_key); 260 data_blob_clear(&server_info->lm_session_key); 261 262 server_info->account_name = talloc_strdup(server_info, "SYSTEM"); 263 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 264 265 server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY"); 266 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 267 268 server_info->full_name = talloc_strdup(server_info, "System"); 269 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 270 271 server_info->logon_script = talloc_strdup(server_info, ""); 272 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 273 274 server_info->profile_path = talloc_strdup(server_info, ""); 275 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 276 277 server_info->home_directory = talloc_strdup(server_info, ""); 278 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 279 280 server_info->home_drive = talloc_strdup(server_info, ""); 281 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 282 283 server_info->logon_server = talloc_strdup(server_info, netbios_name); 284 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); 285 286 server_info->last_logon = 0; 287 server_info->last_logoff = 0; 288 server_info->acct_expiry = 0; 289 server_info->last_password_change = 0; 290 server_info->allow_password_change = 0; 291 server_info->force_password_change = 0; 292 293 server_info->logon_count = 0; 294 server_info->bad_password_count = 0; 295 296 server_info->acct_flags = ACB_NORMAL; 297 298 server_info->authenticated = true; 299 300 *_server_info = server_info; 118 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); 119 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); 120 121 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); 122 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); 123 124 data_blob_clear(&user_info_dc->user_session_key); 125 data_blob_clear(&user_info_dc->lm_session_key); 126 127 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 128 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 129 130 info->account_name = talloc_strdup(info, "SYSTEM"); 131 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 132 133 info->domain_name = talloc_strdup(info, "NT AUTHORITY"); 134 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 135 136 info->full_name = talloc_strdup(info, "System"); 137 NT_STATUS_HAVE_NO_MEMORY(info->full_name); 138 139 info->logon_script = talloc_strdup(info, ""); 140 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 141 142 info->profile_path = talloc_strdup(info, ""); 143 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 144 145 info->home_directory = talloc_strdup(info, ""); 146 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 147 148 info->home_drive = talloc_strdup(info, ""); 149 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 150 151 info->logon_server = talloc_strdup(info, netbios_name); 152 NT_STATUS_HAVE_NO_MEMORY(info->logon_server); 153 154 info->last_logon = 0; 155 info->last_logoff = 0; 156 info->acct_expiry = 0; 157 info->last_password_change = 0; 158 info->allow_password_change = 0; 159 info->force_password_change = 0; 160 161 info->logon_count = 0; 162 info->bad_password_count = 0; 163 164 info->acct_flags = ACB_NORMAL; 165 166 info->authenticated = true; 167 168 *_user_info_dc = user_info_dc; 301 169 302 170 return NT_STATUS_OK; … … 304 172 305 173 306 /* Create server info for the Administrator account. This should only be used 307 * during provisioning when we need to impersonate Administrator but 308 * the account has not been created yet */ 309 310 static NTSTATUS create_admin_token(TALLOC_CTX *mem_ctx, 311 struct dom_sid *user_sid, 312 struct dom_sid *group_sid, 313 int n_groupSIDs, 314 struct dom_sid **groupSIDs, 315 struct security_token **token) 316 { 317 struct security_token *ptoken; 318 int i; 319 320 ptoken = security_token_initialise(mem_ctx); 321 NT_STATUS_HAVE_NO_MEMORY(ptoken); 322 323 ptoken->sids = talloc_array(ptoken, struct dom_sid *, n_groupSIDs + 3); 324 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids); 325 326 ptoken->user_sid = talloc_reference(ptoken, user_sid); 327 ptoken->group_sid = talloc_reference(ptoken, group_sid); 328 ptoken->privilege_mask = 0; 329 330 ptoken->sids[0] = ptoken->user_sid; 331 ptoken->sids[1] = ptoken->group_sid; 332 ptoken->sids[2] = dom_sid_parse_talloc(ptoken->sids, SID_NT_AUTHENTICATED_USERS); 333 NT_STATUS_HAVE_NO_MEMORY(ptoken->sids[2]); 334 ptoken->num_sids = 3; 335 336 337 for (i = 0; i < n_groupSIDs; i++) { 338 size_t check_sid_idx; 339 for (check_sid_idx = 1; 340 check_sid_idx < ptoken->num_sids; 341 check_sid_idx++) { 342 if (dom_sid_equal(ptoken->sids[check_sid_idx], groupSIDs[i])) { 343 break; 344 } 345 } 346 347 if (check_sid_idx == ptoken->num_sids) { 348 ptoken->sids[ptoken->num_sids++] = talloc_reference(ptoken->sids, groupSIDs[i]); 349 } 350 } 351 352 *token = ptoken; 353 ptoken->privilege_mask = ~0; 354 return NT_STATUS_OK; 355 } 356 357 static NTSTATUS auth_domain_admin_server_info(TALLOC_CTX *mem_ctx, 174 static NTSTATUS auth_domain_admin_user_info_dc(TALLOC_CTX *mem_ctx, 358 175 const char *netbios_name, 359 176 const char *domain_name, 360 177 struct dom_sid *domain_sid, 361 struct auth_serversupplied_info **_server_info) 362 { 363 struct auth_serversupplied_info *server_info; 364 365 server_info = talloc(mem_ctx, struct auth_serversupplied_info); 366 NT_STATUS_HAVE_NO_MEMORY(server_info); 367 368 server_info->account_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINISTRATOR); 369 NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid); 370 371 server_info->primary_group_sid = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS); 372 NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid); 373 374 server_info->n_domain_groups = 6; 375 server_info->domain_groups = talloc_array(server_info, struct dom_sid *, server_info->n_domain_groups); 376 377 server_info->domain_groups[0] = dom_sid_parse_talloc(server_info, SID_BUILTIN_ADMINISTRATORS); 378 server_info->domain_groups[1] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ADMINS); 379 server_info->domain_groups[2] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_USERS); 380 server_info->domain_groups[3] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS); 381 server_info->domain_groups[4] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_POLICY_ADMINS); 382 server_info->domain_groups[5] = dom_sid_add_rid(server_info, domain_sid, DOMAIN_RID_SCHEMA_ADMINS); 178 struct auth_user_info_dc **_user_info_dc) 179 { 180 struct auth_user_info_dc *user_info_dc; 181 struct auth_user_info *info; 182 183 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 184 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 185 186 user_info_dc->num_sids = 7; 187 user_info_dc->sids = talloc_array(user_info_dc, struct dom_sid, user_info_dc->num_sids); 188 189 user_info_dc->sids[PRIMARY_USER_SID_INDEX] = *domain_sid; 190 sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_ADMINISTRATOR); 191 192 user_info_dc->sids[PRIMARY_GROUP_SID_INDEX] = *domain_sid; 193 sid_append_rid(&user_info_dc->sids[PRIMARY_USER_SID_INDEX], DOMAIN_RID_USERS); 194 195 user_info_dc->sids[2] = global_sid_Builtin_Administrators; 196 197 user_info_dc->sids[3] = *domain_sid; 198 sid_append_rid(&user_info_dc->sids[3], DOMAIN_RID_ADMINS); 199 user_info_dc->sids[4] = *domain_sid; 200 sid_append_rid(&user_info_dc->sids[4], DOMAIN_RID_ENTERPRISE_ADMINS); 201 user_info_dc->sids[5] = *domain_sid; 202 sid_append_rid(&user_info_dc->sids[5], DOMAIN_RID_POLICY_ADMINS); 203 user_info_dc->sids[6] = *domain_sid; 204 sid_append_rid(&user_info_dc->sids[6], DOMAIN_RID_SCHEMA_ADMINS); 383 205 384 206 /* What should the session key be?*/ 385 server_info->user_session_key = data_blob_talloc(server_info, NULL, 16); 386 NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data); 387 388 server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16); 389 NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data); 390 391 data_blob_clear(&server_info->user_session_key); 392 data_blob_clear(&server_info->lm_session_key); 393 394 server_info->account_name = talloc_strdup(server_info, "Administrator"); 395 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name); 396 397 server_info->domain_name = talloc_strdup(server_info, domain_name); 398 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name); 399 400 server_info->full_name = talloc_strdup(server_info, "Administrator"); 401 NT_STATUS_HAVE_NO_MEMORY(server_info->full_name); 402 403 server_info->logon_script = talloc_strdup(server_info, ""); 404 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script); 405 406 server_info->profile_path = talloc_strdup(server_info, ""); 407 NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path); 408 409 server_info->home_directory = talloc_strdup(server_info, ""); 410 NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory); 411 412 server_info->home_drive = talloc_strdup(server_info, ""); 413 NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive); 414 415 server_info->logon_server = talloc_strdup(server_info, netbios_name); 416 NT_STATUS_HAVE_NO_MEMORY(server_info->logon_server); 417 418 server_info->last_logon = 0; 419 server_info->last_logoff = 0; 420 server_info->acct_expiry = 0; 421 server_info->last_password_change = 0; 422 server_info->allow_password_change = 0; 423 server_info->force_password_change = 0; 424 425 server_info->logon_count = 0; 426 server_info->bad_password_count = 0; 427 428 server_info->acct_flags = ACB_NORMAL; 429 430 server_info->authenticated = true; 431 432 *_server_info = server_info; 207 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); 208 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); 209 210 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); 211 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); 212 213 data_blob_clear(&user_info_dc->user_session_key); 214 data_blob_clear(&user_info_dc->lm_session_key); 215 216 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 217 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 218 219 info->account_name = talloc_strdup(info, "Administrator"); 220 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 221 222 info->domain_name = talloc_strdup(info, domain_name); 223 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 224 225 info->full_name = talloc_strdup(info, "Administrator"); 226 NT_STATUS_HAVE_NO_MEMORY(info->full_name); 227 228 info->logon_script = talloc_strdup(info, ""); 229 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 230 231 info->profile_path = talloc_strdup(info, ""); 232 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 233 234 info->home_directory = talloc_strdup(info, ""); 235 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 236 237 info->home_drive = talloc_strdup(info, ""); 238 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 239 240 info->logon_server = talloc_strdup(info, netbios_name); 241 NT_STATUS_HAVE_NO_MEMORY(info->logon_server); 242 243 info->last_logon = 0; 244 info->last_logoff = 0; 245 info->acct_expiry = 0; 246 info->last_password_change = 0; 247 info->allow_password_change = 0; 248 info->force_password_change = 0; 249 250 info->logon_count = 0; 251 info->bad_password_count = 0; 252 253 info->acct_flags = ACB_NORMAL; 254 255 info->authenticated = true; 256 257 *_user_info_dc = user_info_dc; 433 258 434 259 return NT_STATUS_OK; … … 438 263 struct loadparm_context *lp_ctx, 439 264 struct dom_sid *domain_sid, 440 struct auth_session_info ** _session_info)265 struct auth_session_info **session_info) 441 266 { 442 267 NTSTATUS nt_status; 443 struct auth_serversupplied_info *server_info = NULL; 444 struct auth_session_info *session_info = NULL; 268 struct auth_user_info_dc *user_info_dc = NULL; 445 269 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 446 270 447 nt_status = auth_domain_admin_ server_info(mem_ctx, lp_netbios_name(lp_ctx),448 lp _workgroup(lp_ctx), domain_sid,449 & server_info);271 nt_status = auth_domain_admin_user_info_dc(mem_ctx, lpcfg_netbios_name(lp_ctx), 272 lpcfg_workgroup(lp_ctx), domain_sid, 273 &user_info_dc); 450 274 if (!NT_STATUS_IS_OK(nt_status)) { 451 275 talloc_free(mem_ctx); … … 453 277 } 454 278 455 session_info = talloc(mem_ctx, struct auth_session_info); 456 NT_STATUS_HAVE_NO_MEMORY(session_info); 457 458 session_info->server_info = talloc_reference(session_info, server_info); 459 460 /* unless set otherwise, the session key is the user session 461 * key from the auth subsystem */ 462 session_info->session_key = server_info->user_session_key; 463 464 nt_status = create_admin_token(session_info, 465 server_info->account_sid, 466 server_info->primary_group_sid, 467 server_info->n_domain_groups, 468 server_info->domain_groups, 469 &session_info->security_token); 470 NT_STATUS_NOT_OK_RETURN(nt_status); 471 472 session_info->credentials = cli_credentials_init(session_info); 473 if (!session_info->credentials) { 474 return NT_STATUS_NO_MEMORY; 475 } 476 477 cli_credentials_set_conf(session_info->credentials, lp_ctx); 478 479 *_session_info = session_info; 480 481 return NT_STATUS_OK; 279 nt_status = auth_generate_session_info(mem_ctx, NULL, NULL, user_info_dc, 280 AUTH_SESSION_INFO_SIMPLE_PRIVILEGES|AUTH_SESSION_INFO_AUTHENTICATED|AUTH_SESSION_INFO_DEFAULT_GROUPS, 281 session_info); 282 /* There is already a reference between the sesion_info and user_info_dc */ 283 if (NT_STATUS_IS_OK(nt_status)) { 284 talloc_steal(parent_ctx, *session_info); 285 } 286 talloc_free(mem_ctx); 287 return nt_status; 482 288 } 483 289 … … 495 301 return session_info; 496 302 } 303 304 _PUBLIC_ NTSTATUS auth_anonymous_session_info(TALLOC_CTX *parent_ctx, 305 struct loadparm_context *lp_ctx, 306 struct auth_session_info **_session_info) 307 { 308 NTSTATUS nt_status; 309 struct auth_user_info_dc *user_info_dc = NULL; 310 struct auth_session_info *session_info = NULL; 311 TALLOC_CTX *mem_ctx = talloc_new(parent_ctx); 312 313 nt_status = auth_anonymous_user_info_dc(mem_ctx, 314 lpcfg_netbios_name(lp_ctx), 315 &user_info_dc); 316 if (!NT_STATUS_IS_OK(nt_status)) { 317 talloc_free(mem_ctx); 318 return nt_status; 319 } 320 321 /* references the user_info_dc into the session_info */ 322 nt_status = auth_generate_session_info(parent_ctx, NULL, NULL, user_info_dc, AUTH_SESSION_INFO_SIMPLE_PRIVILEGES, &session_info); 323 talloc_free(mem_ctx); 324 325 NT_STATUS_NOT_OK_RETURN(nt_status); 326 327 session_info->credentials = cli_credentials_init(session_info); 328 if (!session_info->credentials) { 329 return NT_STATUS_NO_MEMORY; 330 } 331 332 cli_credentials_set_conf(session_info->credentials, lp_ctx); 333 cli_credentials_set_anonymous(session_info->credentials); 334 335 *_session_info = session_info; 336 337 return NT_STATUS_OK; 338 } 339 340 _PUBLIC_ NTSTATUS auth_anonymous_user_info_dc(TALLOC_CTX *mem_ctx, 341 const char *netbios_name, 342 struct auth_user_info_dc **_user_info_dc) 343 { 344 struct auth_user_info_dc *user_info_dc; 345 struct auth_user_info *info; 346 user_info_dc = talloc(mem_ctx, struct auth_user_info_dc); 347 NT_STATUS_HAVE_NO_MEMORY(user_info_dc); 348 349 /* This returns a pointer to a struct dom_sid, which is the 350 * same as a 1 element list of struct dom_sid */ 351 user_info_dc->num_sids = 1; 352 user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS); 353 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids); 354 355 /* annoying, but the Anonymous really does have a session key... */ 356 user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16); 357 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data); 358 359 user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16); 360 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data); 361 362 /* and it is all zeros! */ 363 data_blob_clear(&user_info_dc->user_session_key); 364 data_blob_clear(&user_info_dc->lm_session_key); 365 366 user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info); 367 NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info); 368 369 info->account_name = talloc_strdup(info, "ANONYMOUS LOGON"); 370 NT_STATUS_HAVE_NO_MEMORY(info->account_name); 371 372 info->domain_name = talloc_strdup(info, "NT AUTHORITY"); 373 NT_STATUS_HAVE_NO_MEMORY(info->domain_name); 374 375 info->full_name = talloc_strdup(info, "Anonymous Logon"); 376 NT_STATUS_HAVE_NO_MEMORY(info->full_name); 377 378 info->logon_script = talloc_strdup(info, ""); 379 NT_STATUS_HAVE_NO_MEMORY(info->logon_script); 380 381 info->profile_path = talloc_strdup(info, ""); 382 NT_STATUS_HAVE_NO_MEMORY(info->profile_path); 383 384 info->home_directory = talloc_strdup(info, ""); 385 NT_STATUS_HAVE_NO_MEMORY(info->home_directory); 386 387 info->home_drive = talloc_strdup(info, ""); 388 NT_STATUS_HAVE_NO_MEMORY(info->home_drive); 389 390 info->logon_server = talloc_strdup(info, netbios_name); 391 NT_STATUS_HAVE_NO_MEMORY(info->logon_server); 392 393 info->last_logon = 0; 394 info->last_logoff = 0; 395 info->acct_expiry = 0; 396 info->last_password_change = 0; 397 info->allow_password_change = 0; 398 info->force_password_change = 0; 399 400 info->logon_count = 0; 401 info->bad_password_count = 0; 402 403 info->acct_flags = ACB_NORMAL; 404 405 info->authenticated = false; 406 407 *_user_info_dc = user_info_dc; 408 409 return NT_STATUS_OK; 410 } 411
Note:
See TracChangeset
for help on using the changeset viewer.