1 /*
2    NLTMSSP wrappers
3 
4    Copyright (C) Andrew Tridgell      2001
5    Copyright (C) Andrew Bartlett 2001-2003,2011
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "includes.h"
22 #include "auth/ntlmssp/ntlmssp.h"
23 #include "auth_generic.h"
24 #include "auth/gensec/gensec.h"
25 #include "auth/credentials/credentials.h"
26 #include "librpc/rpc/dcerpc.h"
27 #include "lib/param/param.h"
28 #include "librpc/crypto/gse.h"
29 
auth_generic_set_username(struct auth_generic_state * ans,const char * user)30 NTSTATUS auth_generic_set_username(struct auth_generic_state *ans,
31 				   const char *user)
32 {
33 	cli_credentials_set_username(ans->credentials, user, CRED_SPECIFIED);
34 	return NT_STATUS_OK;
35 }
36 
auth_generic_set_domain(struct auth_generic_state * ans,const char * domain)37 NTSTATUS auth_generic_set_domain(struct auth_generic_state *ans,
38 				 const char *domain)
39 {
40 	cli_credentials_set_domain(ans->credentials, domain, CRED_SPECIFIED);
41 	return NT_STATUS_OK;
42 }
43 
auth_generic_set_password(struct auth_generic_state * ans,const char * password)44 NTSTATUS auth_generic_set_password(struct auth_generic_state *ans,
45 				   const char *password)
46 {
47 	cli_credentials_set_password(ans->credentials, password, CRED_SPECIFIED);
48 	return NT_STATUS_OK;
49 }
50 
auth_generic_set_creds(struct auth_generic_state * ans,struct cli_credentials * creds)51 NTSTATUS auth_generic_set_creds(struct auth_generic_state *ans,
52 				struct cli_credentials *creds)
53 {
54 	talloc_unlink(ans->credentials, creds);
55 	ans->credentials = creds;
56 	return NT_STATUS_OK;
57 }
58 
auth_generic_client_prepare(TALLOC_CTX * mem_ctx,struct auth_generic_state ** auth_generic_state)59 NTSTATUS auth_generic_client_prepare(TALLOC_CTX *mem_ctx, struct auth_generic_state **auth_generic_state)
60 {
61 	struct auth_generic_state *ans;
62 	NTSTATUS nt_status;
63 	size_t idx = 0;
64 	struct gensec_settings *gensec_settings;
65 	const struct gensec_security_ops **backends = NULL;
66 	struct loadparm_context *lp_ctx;
67 
68 	ans = talloc_zero(mem_ctx, struct auth_generic_state);
69 	if (!ans) {
70 		DEBUG(0,("auth_generic_start: talloc failed!\n"));
71 		return NT_STATUS_NO_MEMORY;
72 	}
73 
74 	lp_ctx = loadparm_init_s3(ans, loadparm_s3_helpers());
75 	if (lp_ctx == NULL) {
76 		DEBUG(10, ("loadparm_init_s3 failed\n"));
77 		TALLOC_FREE(ans);
78 		return NT_STATUS_INVALID_SERVER_STATE;
79 	}
80 
81 	gensec_settings = lpcfg_gensec_settings(ans, lp_ctx);
82 	if (lp_ctx == NULL) {
83 		DEBUG(10, ("lpcfg_gensec_settings failed\n"));
84 		TALLOC_FREE(ans);
85 		return NT_STATUS_NO_MEMORY;
86 	}
87 
88 	backends = talloc_zero_array(gensec_settings,
89 				     const struct gensec_security_ops *, 7);
90 	if (backends == NULL) {
91 		TALLOC_FREE(ans);
92 		return NT_STATUS_NO_MEMORY;
93 	}
94 	gensec_settings->backends = backends;
95 
96 	gensec_init();
97 
98 	/* These need to be in priority order, krb5 before NTLMSSP */
99 #if defined(HAVE_KRB5)
100 	backends[idx++] = &gensec_gse_krb5_security_ops;
101 #endif
102 
103 	backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
104 	backends[idx++] = gensec_security_by_name(NULL, "ntlmssp_resume_ccache");
105 
106 	backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
107 	backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
108 	backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
109 
110 	nt_status = gensec_client_start(ans, &ans->gensec_security, gensec_settings);
111 
112 	if (!NT_STATUS_IS_OK(nt_status)) {
113 		TALLOC_FREE(ans);
114 		return nt_status;
115 	}
116 
117 	ans->credentials = cli_credentials_init(ans);
118 	if (!ans->credentials) {
119 		TALLOC_FREE(ans);
120 		return NT_STATUS_NO_MEMORY;
121 	}
122 
123 	cli_credentials_guess(ans->credentials, lp_ctx);
124 
125 	talloc_unlink(ans, lp_ctx);
126 	talloc_unlink(ans, gensec_settings);
127 
128 	*auth_generic_state = ans;
129 	return NT_STATUS_OK;
130 }
131 
auth_generic_client_start(struct auth_generic_state * ans,const char * oid)132 NTSTATUS auth_generic_client_start(struct auth_generic_state *ans, const char *oid)
133 {
134 	NTSTATUS status;
135 
136 	/* Transfer the credentials to gensec */
137 	status = gensec_set_credentials(ans->gensec_security, ans->credentials);
138 	if (!NT_STATUS_IS_OK(status)) {
139 		DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
140 			  nt_errstr(status)));
141 		return status;
142 	}
143 	talloc_unlink(ans, ans->credentials);
144 	ans->credentials = NULL;
145 
146 	status = gensec_start_mech_by_oid(ans->gensec_security,
147 					  oid);
148 	if (!NT_STATUS_IS_OK(status)) {
149 		return status;
150 	}
151 
152 	return NT_STATUS_OK;
153 }
154 
auth_generic_client_start_by_name(struct auth_generic_state * ans,const char * name)155 NTSTATUS auth_generic_client_start_by_name(struct auth_generic_state *ans,
156 					   const char *name)
157 {
158 	NTSTATUS status;
159 
160 	/* Transfer the credentials to gensec */
161 	status = gensec_set_credentials(ans->gensec_security, ans->credentials);
162 	if (!NT_STATUS_IS_OK(status)) {
163 		DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
164 			  nt_errstr(status)));
165 		return status;
166 	}
167 	talloc_unlink(ans, ans->credentials);
168 	ans->credentials = NULL;
169 
170 	status = gensec_start_mech_by_name(ans->gensec_security, name);
171 	if (!NT_STATUS_IS_OK(status)) {
172 		return status;
173 	}
174 
175 	return NT_STATUS_OK;
176 }
177 
auth_generic_client_start_by_authtype(struct auth_generic_state * ans,uint8_t auth_type,uint8_t auth_level)178 NTSTATUS auth_generic_client_start_by_authtype(struct auth_generic_state *ans,
179 					       uint8_t auth_type,
180 					       uint8_t auth_level)
181 {
182 	NTSTATUS status;
183 
184 	/* Transfer the credentials to gensec */
185 	status = gensec_set_credentials(ans->gensec_security, ans->credentials);
186 	if (!NT_STATUS_IS_OK(status)) {
187 		DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
188 			  nt_errstr(status)));
189 		return status;
190 	}
191 	talloc_unlink(ans, ans->credentials);
192 	ans->credentials = NULL;
193 
194 	status = gensec_start_mech_by_authtype(ans->gensec_security,
195 					       auth_type, auth_level);
196 	if (!NT_STATUS_IS_OK(status)) {
197 		return status;
198 	}
199 
200 	return NT_STATUS_OK;
201 }
202 
auth_generic_client_start_by_sasl(struct auth_generic_state * ans,const char ** sasl_list)203 NTSTATUS auth_generic_client_start_by_sasl(struct auth_generic_state *ans,
204 					   const char **sasl_list)
205 {
206 	NTSTATUS status;
207 
208 	/* Transfer the credentials to gensec */
209 	status = gensec_set_credentials(ans->gensec_security, ans->credentials);
210 	if (!NT_STATUS_IS_OK(status)) {
211 		DEBUG(1, ("Failed to set GENSEC credentials: %s\n",
212 			  nt_errstr(status)));
213 		return status;
214 	}
215 	talloc_unlink(ans, ans->credentials);
216 	ans->credentials = NULL;
217 
218 	status = gensec_start_mech_by_sasl_list(ans->gensec_security, sasl_list);
219 	if (!NT_STATUS_IS_OK(status)) {
220 		return status;
221 	}
222 
223 	return NT_STATUS_OK;
224 }
225