ctags: Ignore source3/includes/proto.h for tags.
[samba.git] / source3 / rpc_client / init_netlogon.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Guenther Deschner                  2008.
5  *
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.
10  *
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.
15  *
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/>.
18  */
19
20 #include "includes.h"
21
22 /*******************************************************************
23  inits a structure.
24 ********************************************************************/
25
26 void init_netr_SamBaseInfo(struct netr_SamBaseInfo *r,
27                            NTTIME last_logon,
28                            NTTIME last_logoff,
29                            NTTIME acct_expiry,
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,
39                            uint16_t logon_count,
40                            uint16_t bad_password_count,
41                            uint32_t rid,
42                            uint32_t primary_gid,
43                            struct samr_RidWithAttributeArray groups,
44                            uint32_t user_flags,
45                            struct netr_UserSessionKey key,
46                            const char *logon_server,
47                            const char *domain,
48                            struct dom_sid2 *domain_sid,
49                            struct netr_LMSessionKey LMSessKey,
50                            uint32_t acct_flags)
51 {
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;
66         r->rid = rid;
67         r->primary_gid = primary_gid;
68         r->groups = groups;
69         r->user_flags = user_flags;
70         r->key = key;
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;
76 }
77
78 /*******************************************************************
79  inits a structure.
80 ********************************************************************/
81
82 void init_netr_SamInfo3(struct netr_SamInfo3 *r,
83                         NTTIME last_logon,
84                         NTTIME last_logoff,
85                         NTTIME acct_expiry,
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,
95                         uint16_t logon_count,
96                         uint16_t bad_password_count,
97                         uint32_t rid,
98                         uint32_t primary_gid,
99                         struct samr_RidWithAttributeArray groups,
100                         uint32_t user_flags,
101                         struct netr_UserSessionKey key,
102                         const char *logon_server,
103                         const char *domain,
104                         struct dom_sid2 *domain_sid,
105                         struct netr_LMSessionKey LMSessKey,
106                         uint32_t acct_flags,
107                         uint32_t sidcount,
108                         struct netr_SidAttr *sids)
109 {
110         init_netr_SamBaseInfo(&r->base,
111                               last_logon,
112                               last_logoff,
113                               acct_expiry,
114                               last_password_change,
115                               allow_password_change,
116                               force_password_change,
117                               account_name,
118                               full_name,
119                               logon_script,
120                               profile_path,
121                               home_directory,
122                               home_drive,
123                               logon_count,
124                               bad_password_count,
125                               rid,
126                               primary_gid,
127                               groups,
128                               user_flags,
129                               key,
130                               logon_server,
131                               domain,
132                               domain_sid,
133                               LMSessKey,
134                               acct_flags);
135         r->sidcount = sidcount;
136         r->sids = sids;
137 }
138
139 /*******************************************************************
140  gets a domain user's groups from their already-calculated NT_USER_TOKEN
141  ********************************************************************/
142
143 static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx,
144                                        const DOM_SID *domain_sid,
145                                        size_t num_sids,
146                                        const DOM_SID *sids,
147                                        int *numgroups, DOM_GID **pgids)
148 {
149         int i;
150
151         *numgroups=0;
152         *pgids = NULL;
153
154         for (i=0; i<num_sids; i++) {
155                 DOM_GID gid;
156                 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.g_rid)) {
157                         continue;
158                 }
159                 gid.attr = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
160                             SE_GROUP_ENABLED);
161                 ADD_TO_ARRAY(mem_ctx, DOM_GID, gid, pgids, numgroups);
162                 if (*pgids == NULL) {
163                         return NT_STATUS_NO_MEMORY;
164                 }
165         }
166         return NT_STATUS_OK;
167 }
168
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 *****************************************************************************/
173
174 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
175                                 uint8_t *pipe_session_key,
176                                 size_t pipe_session_key_len,
177                                 struct netr_SamInfo3 *sam3)
178 {
179         struct samu *sampw;
180         DOM_GID *gids = NULL;
181         const DOM_SID *user_sid = NULL;
182         const DOM_SID *group_sid = NULL;
183         DOM_SID domain_sid;
184         uint32 user_rid, group_rid;
185         NTSTATUS status;
186
187         int num_gids = 0;
188         const char *my_name;
189
190         struct netr_UserSessionKey user_session_key;
191         struct netr_LMSessionKey lm_session_key;
192
193         NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
194         NTTIME allow_password_change, force_password_change;
195         struct samr_RidWithAttributeArray groups;
196         int i;
197         struct dom_sid2 *sid = NULL;
198
199         ZERO_STRUCT(user_session_key);
200         ZERO_STRUCT(lm_session_key);
201
202         sampw = server_info->sam_account;
203
204         user_sid = pdb_get_user_sid(sampw);
205         group_sid = pdb_get_group_sid(sampw);
206
207         if (pipe_session_key && pipe_session_key_len != 16) {
208                 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
209                          "pipe_session_key_len[%u] != 16\n",
210                          pipe_session_key_len));
211                 return NT_STATUS_INTERNAL_ERROR;
212         }
213
214         if ((user_sid == NULL) || (group_sid == NULL)) {
215                 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
216                 return NT_STATUS_UNSUCCESSFUL;
217         }
218
219         sid_copy(&domain_sid, user_sid);
220         sid_split_rid(&domain_sid, &user_rid);
221
222         sid = sid_dup_talloc(sam3, &domain_sid);
223         if (!sid) {
224                 return NT_STATUS_NO_MEMORY;
225         }
226
227         if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
228                 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
229                           "%s\n but group sid %s.\n"
230                           "The conflicting domain portions are not "
231                           "supported for NETLOGON calls\n",
232                           pdb_get_domain(sampw),
233                           pdb_get_username(sampw),
234                           sid_string_dbg(user_sid),
235                           sid_string_dbg(group_sid)));
236                 return NT_STATUS_UNSUCCESSFUL;
237         }
238
239         if(server_info->login_server) {
240                 my_name = server_info->login_server;
241         } else {
242                 my_name = global_myname();
243         }
244
245         status = nt_token_to_group_list(sam3, &domain_sid,
246                                         server_info->num_sids,
247                                         server_info->sids,
248                                         &num_gids, &gids);
249
250         if (!NT_STATUS_IS_OK(status)) {
251                 return status;
252         }
253
254         if (server_info->user_session_key.length) {
255                 memcpy(user_session_key.key,
256                        server_info->user_session_key.data,
257                        MIN(sizeof(user_session_key.key),
258                            server_info->user_session_key.length));
259                 if (pipe_session_key) {
260                         SamOEMhash(user_session_key.key, pipe_session_key, 16);
261                 }
262         }
263         if (server_info->lm_session_key.length) {
264                 memcpy(lm_session_key.key,
265                        server_info->lm_session_key.data,
266                        MIN(sizeof(lm_session_key.key),
267                            server_info->lm_session_key.length));
268                 if (pipe_session_key) {
269                         SamOEMhash(lm_session_key.key, pipe_session_key, 8);
270                 }
271         }
272
273         groups.count = num_gids;
274         groups.rids = TALLOC_ARRAY(sam3, struct samr_RidWithAttribute, groups.count);
275         if (!groups.rids) {
276                 return NT_STATUS_NO_MEMORY;
277         }
278
279         for (i=0; i < groups.count; i++) {
280                 groups.rids[i].rid = gids[i].g_rid;
281                 groups.rids[i].attributes = gids[i].attr;
282         }
283
284         unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
285         unix_to_nt_time(&last_logoff, get_time_t_max());
286         unix_to_nt_time(&acct_expiry, get_time_t_max());
287         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
288         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
289         unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
290
291         init_netr_SamInfo3(sam3,
292                            last_logon,
293                            last_logoff,
294                            acct_expiry,
295                            last_password_change,
296                            allow_password_change,
297                            force_password_change,
298                            talloc_strdup(sam3, pdb_get_username(sampw)),
299                            talloc_strdup(sam3, pdb_get_fullname(sampw)),
300                            talloc_strdup(sam3, pdb_get_logon_script(sampw)),
301                            talloc_strdup(sam3, pdb_get_profile_path(sampw)),
302                            talloc_strdup(sam3, pdb_get_homedir(sampw)),
303                            talloc_strdup(sam3, pdb_get_dir_drive(sampw)),
304                            0, /* logon_count */
305                            0, /* bad_password_count */
306                            user_rid,
307                            group_rid,
308                            groups,
309                            NETLOGON_EXTRA_SIDS,
310                            user_session_key,
311                            my_name,
312                            talloc_strdup(sam3, pdb_get_domain(sampw)),
313                            sid,
314                            lm_session_key,
315                            pdb_get_acct_ctrl(sampw),
316                            0, /* sidcount */
317                            NULL); /* struct netr_SidAttr *sids */
318         ZERO_STRUCT(user_session_key);
319         ZERO_STRUCT(lm_session_key);
320
321         return NT_STATUS_OK;
322 }
323
324 /*******************************************************************
325  inits a structure.
326 ********************************************************************/
327
328 void init_netr_IdentityInfo(struct netr_IdentityInfo *r,
329                             const char *domain_name,
330                             uint32_t parameter_control,
331                             uint32_t logon_id_low,
332                             uint32_t logon_id_high,
333                             const char *account_name,
334                             const char *workstation)
335 {
336         init_lsa_String(&r->domain_name, domain_name);
337         r->parameter_control = parameter_control;
338         r->logon_id_low = logon_id_low;
339         r->logon_id_high = logon_id_high;
340         init_lsa_String(&r->account_name, account_name);
341         init_lsa_String(&r->workstation, workstation);
342 }
343
344 /*******************************************************************
345  inits a structure.
346  This is a network logon packet. The log_id parameters
347  are what an NT server would generate for LUID once the
348  user is logged on. I don't think we care about them.
349
350  Note that this has no access to the NT and LM hashed passwords,
351  so it forwards the challenge, and the NT and LM responses (24
352  bytes each) over the secure channel to the Domain controller
353  for it to say yea or nay. This is the preferred method of
354  checking for a logon as it doesn't export the password
355  hashes to anyone who has compromised the secure channel. JRA.
356
357 ********************************************************************/
358
359 void init_netr_NetworkInfo(struct netr_NetworkInfo *r,
360                            const char *domain_name,
361                            uint32_t parameter_control,
362                            uint32_t logon_id_low,
363                            uint32_t logon_id_high,
364                            const char *account_name,
365                            const char *workstation,
366                            uint8_t challenge[8],
367                            struct netr_ChallengeResponse nt,
368                            struct netr_ChallengeResponse lm)
369 {
370         init_netr_IdentityInfo(&r->identity_info,
371                                domain_name,
372                                parameter_control,
373                                logon_id_low,
374                                logon_id_high,
375                                account_name,
376                                workstation);
377         memcpy(r->challenge, challenge, 8);
378         r->nt = nt;
379         r->lm = lm;
380 }
381
382 /*******************************************************************
383  inits a structure.
384 ********************************************************************/
385
386 void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
387                             const char *domain_name,
388                             uint32_t parameter_control,
389                             uint32_t logon_id_low,
390                             uint32_t logon_id_high,
391                             const char *account_name,
392                             const char *workstation,
393                             struct samr_Password lmpassword,
394                             struct samr_Password ntpassword)
395 {
396         init_netr_IdentityInfo(&r->identity_info,
397                                domain_name,
398                                parameter_control,
399                                logon_id_low,
400                                logon_id_high,
401                                account_name,
402                                workstation);
403         r->lmpassword = lmpassword;
404         r->ntpassword = ntpassword;
405 }
406
407 /*************************************************************************
408  inits a netr_CryptPassword structure
409  *************************************************************************/
410
411 void init_netr_CryptPassword(const char *pwd,
412                              unsigned char session_key[16],
413                              struct netr_CryptPassword *pwd_buf)
414 {
415         struct samr_CryptPassword password_buf;
416
417         encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
418
419         SamOEMhash(password_buf.data, session_key, 516);
420         memcpy(pwd_buf->data, password_buf.data, 512);
421         pwd_buf->length = IVAL(password_buf.data, 512);
422 }