2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Guenther Deschner 2008.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 /*******************************************************************
24 ********************************************************************/
26 void init_netr_SamBaseInfo(struct netr_SamBaseInfo
*r
,
30 NTTIME last_password_change
,
31 NTTIME allow_password_change
,
32 NTTIME force_password_change
,
33 const char *account_name
,
34 const char *full_name
,
35 const char *logon_script
,
36 const char *profile_path
,
37 const char *home_directory
,
38 const char *home_drive
,
40 uint16_t bad_password_count
,
43 struct samr_RidWithAttributeArray groups
,
45 struct netr_UserSessionKey key
,
46 const char *logon_server
,
48 struct dom_sid2
*domain_sid
,
49 struct netr_LMSessionKey LMSessKey
,
52 r
->last_logon
= last_logon
;
53 r
->last_logoff
= last_logoff
;
54 r
->acct_expiry
= acct_expiry
;
55 r
->last_password_change
= last_password_change
;
56 r
->allow_password_change
= allow_password_change
;
57 r
->force_password_change
= force_password_change
;
58 init_lsa_String(&r
->account_name
, account_name
);
59 init_lsa_String(&r
->full_name
, full_name
);
60 init_lsa_String(&r
->logon_script
, logon_script
);
61 init_lsa_String(&r
->profile_path
, profile_path
);
62 init_lsa_String(&r
->home_directory
, home_directory
);
63 init_lsa_String(&r
->home_drive
, home_drive
);
64 r
->logon_count
= logon_count
;
65 r
->bad_password_count
= bad_password_count
;
67 r
->primary_gid
= primary_gid
;
69 r
->user_flags
= user_flags
;
71 init_lsa_StringLarge(&r
->logon_server
, logon_server
);
72 init_lsa_StringLarge(&r
->domain
, domain
);
73 r
->domain_sid
= domain_sid
;
74 r
->LMSessKey
= LMSessKey
;
75 r
->acct_flags
= acct_flags
;
78 /*******************************************************************
80 ********************************************************************/
82 void init_netr_SamInfo3(struct netr_SamInfo3
*r
,
86 NTTIME last_password_change
,
87 NTTIME allow_password_change
,
88 NTTIME force_password_change
,
89 const char *account_name
,
90 const char *full_name
,
91 const char *logon_script
,
92 const char *profile_path
,
93 const char *home_directory
,
94 const char *home_drive
,
96 uint16_t bad_password_count
,
99 struct samr_RidWithAttributeArray groups
,
101 struct netr_UserSessionKey key
,
102 const char *logon_server
,
104 struct dom_sid2
*domain_sid
,
105 struct netr_LMSessionKey LMSessKey
,
108 struct netr_SidAttr
*sids
)
110 init_netr_SamBaseInfo(&r
->base
,
114 last_password_change
,
115 allow_password_change
,
116 force_password_change
,
135 r
->sidcount
= sidcount
;
139 /*******************************************************************
140 gets a domain user's groups from their already-calculated NT_USER_TOKEN
141 ********************************************************************/
143 static NTSTATUS
nt_token_to_group_list(TALLOC_CTX
*mem_ctx
,
144 const DOM_SID
*domain_sid
,
147 int *numgroups
, DOM_GID
**pgids
)
154 for (i
=0; i
<num_sids
; i
++) {
156 if (!sid_peek_check_rid(domain_sid
, &sids
[i
], &gid
.g_rid
)) {
159 gid
.attr
= (SE_GROUP_MANDATORY
|SE_GROUP_ENABLED_BY_DEFAULT
|
161 ADD_TO_ARRAY(mem_ctx
, DOM_GID
, gid
, pgids
, numgroups
);
162 if (*pgids
== NULL
) {
163 return NT_STATUS_NO_MEMORY
;
169 /****************************************************************************
170 inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
171 already be initialized and is used as the talloc parent for its members.
172 *****************************************************************************/
174 NTSTATUS
serverinfo_to_SamInfo3(struct auth_serversupplied_info
*server_info
,
175 uint8_t pipe_session_key
[16],
176 struct netr_SamInfo3
*sam3
)
179 DOM_GID
*gids
= NULL
;
180 const DOM_SID
*user_sid
= NULL
;
181 const DOM_SID
*group_sid
= NULL
;
183 uint32 user_rid
, group_rid
;
189 struct netr_UserSessionKey user_session_key
;
190 struct netr_LMSessionKey lm_session_key
;
192 NTTIME last_logon
, last_logoff
, acct_expiry
, last_password_change
;
193 NTTIME allow_password_change
, force_password_change
;
194 struct samr_RidWithAttributeArray groups
;
196 struct dom_sid2
*sid
= NULL
;
198 ZERO_STRUCT(user_session_key
);
199 ZERO_STRUCT(lm_session_key
);
201 sampw
= server_info
->sam_account
;
203 user_sid
= pdb_get_user_sid(sampw
);
204 group_sid
= pdb_get_group_sid(sampw
);
206 if ((user_sid
== NULL
) || (group_sid
== NULL
)) {
207 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
208 return NT_STATUS_UNSUCCESSFUL
;
211 sid_copy(&domain_sid
, user_sid
);
212 sid_split_rid(&domain_sid
, &user_rid
);
214 sid
= sid_dup_talloc(sam3
, &domain_sid
);
216 return NT_STATUS_NO_MEMORY
;
219 if (!sid_peek_check_rid(&domain_sid
, group_sid
, &group_rid
)) {
220 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
221 "%s\n but group sid %s.\n"
222 "The conflicting domain portions are not "
223 "supported for NETLOGON calls\n",
224 pdb_get_domain(sampw
),
225 pdb_get_username(sampw
),
226 sid_string_dbg(user_sid
),
227 sid_string_dbg(group_sid
)));
228 return NT_STATUS_UNSUCCESSFUL
;
231 if(server_info
->login_server
) {
232 my_name
= server_info
->login_server
;
234 my_name
= global_myname();
237 status
= nt_token_to_group_list(sam3
, &domain_sid
,
238 server_info
->num_sids
,
242 if (!NT_STATUS_IS_OK(status
)) {
246 if (server_info
->user_session_key
.length
) {
247 memcpy(user_session_key
.key
,
248 server_info
->user_session_key
.data
,
249 MIN(sizeof(user_session_key
.key
),
250 server_info
->user_session_key
.length
));
251 SamOEMhash(user_session_key
.key
, pipe_session_key
, 16);
253 if (server_info
->lm_session_key
.length
) {
254 memcpy(lm_session_key
.key
,
255 server_info
->lm_session_key
.data
,
256 MIN(sizeof(lm_session_key
.key
),
257 server_info
->lm_session_key
.length
));
258 SamOEMhash(lm_session_key
.key
, pipe_session_key
, 8);
261 groups
.count
= num_gids
;
262 groups
.rids
= TALLOC_ARRAY(sam3
, struct samr_RidWithAttribute
, groups
.count
);
264 return NT_STATUS_NO_MEMORY
;
267 for (i
=0; i
< groups
.count
; i
++) {
268 groups
.rids
[i
].rid
= gids
[i
].g_rid
;
269 groups
.rids
[i
].attributes
= gids
[i
].attr
;
272 unix_to_nt_time(&last_logon
, pdb_get_logon_time(sampw
));
273 unix_to_nt_time(&last_logoff
, get_time_t_max());
274 unix_to_nt_time(&acct_expiry
, get_time_t_max());
275 unix_to_nt_time(&last_password_change
, pdb_get_pass_last_set_time(sampw
));
276 unix_to_nt_time(&allow_password_change
, pdb_get_pass_can_change_time(sampw
));
277 unix_to_nt_time(&force_password_change
, pdb_get_pass_must_change_time(sampw
));
279 init_netr_SamInfo3(sam3
,
283 last_password_change
,
284 allow_password_change
,
285 force_password_change
,
286 talloc_strdup(sam3
, pdb_get_username(sampw
)),
287 talloc_strdup(sam3
, pdb_get_fullname(sampw
)),
288 talloc_strdup(sam3
, pdb_get_logon_script(sampw
)),
289 talloc_strdup(sam3
, pdb_get_profile_path(sampw
)),
290 talloc_strdup(sam3
, pdb_get_homedir(sampw
)),
291 talloc_strdup(sam3
, pdb_get_dir_drive(sampw
)),
293 0, /* bad_password_count */
300 talloc_strdup(sam3
, pdb_get_domain(sampw
)),
303 pdb_get_acct_ctrl(sampw
),
305 NULL
); /* struct netr_SidAttr *sids */
306 ZERO_STRUCT(user_session_key
);
307 ZERO_STRUCT(lm_session_key
);
312 /*******************************************************************
314 ********************************************************************/
316 void init_netr_IdentityInfo(struct netr_IdentityInfo
*r
,
317 const char *domain_name
,
318 uint32_t parameter_control
,
319 uint32_t logon_id_low
,
320 uint32_t logon_id_high
,
321 const char *account_name
,
322 const char *workstation
)
324 init_lsa_String(&r
->domain_name
, domain_name
);
325 r
->parameter_control
= parameter_control
;
326 r
->logon_id_low
= logon_id_low
;
327 r
->logon_id_high
= logon_id_high
;
328 init_lsa_String(&r
->account_name
, account_name
);
329 init_lsa_String(&r
->workstation
, workstation
);
332 /*******************************************************************
334 This is a network logon packet. The log_id parameters
335 are what an NT server would generate for LUID once the
336 user is logged on. I don't think we care about them.
338 Note that this has no access to the NT and LM hashed passwords,
339 so it forwards the challenge, and the NT and LM responses (24
340 bytes each) over the secure channel to the Domain controller
341 for it to say yea or nay. This is the preferred method of
342 checking for a logon as it doesn't export the password
343 hashes to anyone who has compromised the secure channel. JRA.
345 ********************************************************************/
347 void init_netr_NetworkInfo(struct netr_NetworkInfo
*r
,
348 const char *domain_name
,
349 uint32_t parameter_control
,
350 uint32_t logon_id_low
,
351 uint32_t logon_id_high
,
352 const char *account_name
,
353 const char *workstation
,
354 uint8_t challenge
[8],
355 struct netr_ChallengeResponse nt
,
356 struct netr_ChallengeResponse lm
)
358 init_netr_IdentityInfo(&r
->identity_info
,
365 memcpy(r
->challenge
, challenge
, 8);
370 /*******************************************************************
372 ********************************************************************/
374 void init_netr_PasswordInfo(struct netr_PasswordInfo
*r
,
375 const char *domain_name
,
376 uint32_t parameter_control
,
377 uint32_t logon_id_low
,
378 uint32_t logon_id_high
,
379 const char *account_name
,
380 const char *workstation
,
381 struct samr_Password lmpassword
,
382 struct samr_Password ntpassword
)
384 init_netr_IdentityInfo(&r
->identity_info
,
391 r
->lmpassword
= lmpassword
;
392 r
->ntpassword
= ntpassword
;
395 /*************************************************************************
396 inits a netr_CryptPassword structure
397 *************************************************************************/
399 void init_netr_CryptPassword(const char *pwd
,
400 unsigned char session_key
[16],
401 struct netr_CryptPassword
*pwd_buf
)
403 struct samr_CryptPassword password_buf
;
405 encode_pw_buffer(password_buf
.data
, pwd
, STR_UNICODE
);
407 SamOEMhash(password_buf
.data
, session_key
, 516);
408 memcpy(pwd_buf
->data
, password_buf
.data
, 512);
409 pwd_buf
->length
= IVAL(password_buf
.data
, 512);