Added ability to revert to old modules for make revert.
[bbaumbach/samba-autobuild/.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,
148                                        struct samr_RidWithAttribute **pgids)
149 {
150         int i;
151
152         *numgroups=0;
153         *pgids = NULL;
154
155         for (i=0; i<num_sids; i++) {
156                 struct samr_RidWithAttribute gid;
157                 if (!sid_peek_check_rid(domain_sid, &sids[i], &gid.rid)) {
158                         continue;
159                 }
160                 gid.attributes = (SE_GROUP_MANDATORY|SE_GROUP_ENABLED_BY_DEFAULT|
161                             SE_GROUP_ENABLED);
162                 ADD_TO_ARRAY(mem_ctx, struct samr_RidWithAttribute,
163                              gid, pgids, numgroups);
164                 if (*pgids == NULL) {
165                         return NT_STATUS_NO_MEMORY;
166                 }
167         }
168         return NT_STATUS_OK;
169 }
170
171 /****************************************************************************
172  inits a netr_SamInfo3 structure from an auth_serversupplied_info. sam3 must
173  already be initialized and is used as the talloc parent for its members.
174 *****************************************************************************/
175
176 NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info,
177                                 uint8_t *pipe_session_key,
178                                 size_t pipe_session_key_len,
179                                 struct netr_SamInfo3 *sam3)
180 {
181         struct samu *sampw;
182         struct samr_RidWithAttribute *gids = NULL;
183         const DOM_SID *user_sid = NULL;
184         const DOM_SID *group_sid = NULL;
185         DOM_SID domain_sid;
186         uint32 user_rid, group_rid;
187         NTSTATUS status;
188
189         int num_gids = 0;
190         const char *my_name;
191
192         struct netr_UserSessionKey user_session_key;
193         struct netr_LMSessionKey lm_session_key;
194
195         NTTIME last_logon, last_logoff, acct_expiry, last_password_change;
196         NTTIME allow_password_change, force_password_change;
197         struct samr_RidWithAttributeArray groups;
198         int i;
199         struct dom_sid2 *sid = NULL;
200
201         ZERO_STRUCT(user_session_key);
202         ZERO_STRUCT(lm_session_key);
203
204         sampw = server_info->sam_account;
205
206         user_sid = pdb_get_user_sid(sampw);
207         group_sid = pdb_get_group_sid(sampw);
208
209         if (pipe_session_key && pipe_session_key_len != 16) {
210                 DEBUG(0,("serverinfo_to_SamInfo3: invalid "
211                          "pipe_session_key_len[%zu] != 16\n",
212                          pipe_session_key_len));
213                 return NT_STATUS_INTERNAL_ERROR;
214         }
215
216         if ((user_sid == NULL) || (group_sid == NULL)) {
217                 DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n"));
218                 return NT_STATUS_UNSUCCESSFUL;
219         }
220
221         sid_copy(&domain_sid, user_sid);
222         sid_split_rid(&domain_sid, &user_rid);
223
224         sid = sid_dup_talloc(sam3, &domain_sid);
225         if (!sid) {
226                 return NT_STATUS_NO_MEMORY;
227         }
228
229         if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
230                 DEBUG(1, ("_netr_LogonSamLogon: user %s\\%s has user sid "
231                           "%s\n but group sid %s.\n"
232                           "The conflicting domain portions are not "
233                           "supported for NETLOGON calls\n",
234                           pdb_get_domain(sampw),
235                           pdb_get_username(sampw),
236                           sid_string_dbg(user_sid),
237                           sid_string_dbg(group_sid)));
238                 return NT_STATUS_UNSUCCESSFUL;
239         }
240
241         if(server_info->login_server) {
242                 my_name = server_info->login_server;
243         } else {
244                 my_name = global_myname();
245         }
246
247         status = nt_token_to_group_list(sam3, &domain_sid,
248                                         server_info->num_sids,
249                                         server_info->sids,
250                                         &num_gids, &gids);
251
252         if (!NT_STATUS_IS_OK(status)) {
253                 return status;
254         }
255
256         if (server_info->user_session_key.length) {
257                 memcpy(user_session_key.key,
258                        server_info->user_session_key.data,
259                        MIN(sizeof(user_session_key.key),
260                            server_info->user_session_key.length));
261                 if (pipe_session_key) {
262                         SamOEMhash(user_session_key.key, pipe_session_key, 16);
263                 }
264         }
265         if (server_info->lm_session_key.length) {
266                 memcpy(lm_session_key.key,
267                        server_info->lm_session_key.data,
268                        MIN(sizeof(lm_session_key.key),
269                            server_info->lm_session_key.length));
270                 if (pipe_session_key) {
271                         SamOEMhash(lm_session_key.key, pipe_session_key, 8);
272                 }
273         }
274
275         groups.count = num_gids;
276         groups.rids = TALLOC_ARRAY(sam3, struct samr_RidWithAttribute, groups.count);
277         if (!groups.rids) {
278                 return NT_STATUS_NO_MEMORY;
279         }
280
281         for (i=0; i < groups.count; i++) {
282                 groups.rids[i].rid = gids[i].rid;
283                 groups.rids[i].attributes = gids[i].attributes;
284         }
285
286         unix_to_nt_time(&last_logon, pdb_get_logon_time(sampw));
287         unix_to_nt_time(&last_logoff, get_time_t_max());
288         unix_to_nt_time(&acct_expiry, get_time_t_max());
289         unix_to_nt_time(&last_password_change, pdb_get_pass_last_set_time(sampw));
290         unix_to_nt_time(&allow_password_change, pdb_get_pass_can_change_time(sampw));
291         unix_to_nt_time(&force_password_change, pdb_get_pass_must_change_time(sampw));
292
293         init_netr_SamInfo3(sam3,
294                            last_logon,
295                            last_logoff,
296                            acct_expiry,
297                            last_password_change,
298                            allow_password_change,
299                            force_password_change,
300                            talloc_strdup(sam3, pdb_get_username(sampw)),
301                            talloc_strdup(sam3, pdb_get_fullname(sampw)),
302                            talloc_strdup(sam3, pdb_get_logon_script(sampw)),
303                            talloc_strdup(sam3, pdb_get_profile_path(sampw)),
304                            talloc_strdup(sam3, pdb_get_homedir(sampw)),
305                            talloc_strdup(sam3, pdb_get_dir_drive(sampw)),
306                            0, /* logon_count */
307                            0, /* bad_password_count */
308                            user_rid,
309                            group_rid,
310                            groups,
311                            NETLOGON_EXTRA_SIDS,
312                            user_session_key,
313                            my_name,
314                            talloc_strdup(sam3, pdb_get_domain(sampw)),
315                            sid,
316                            lm_session_key,
317                            pdb_get_acct_ctrl(sampw),
318                            0, /* sidcount */
319                            NULL); /* struct netr_SidAttr *sids */
320         ZERO_STRUCT(user_session_key);
321         ZERO_STRUCT(lm_session_key);
322
323         return NT_STATUS_OK;
324 }
325
326 /*******************************************************************
327  inits a structure.
328 ********************************************************************/
329
330 void init_netr_IdentityInfo(struct netr_IdentityInfo *r,
331                             const char *domain_name,
332                             uint32_t parameter_control,
333                             uint32_t logon_id_low,
334                             uint32_t logon_id_high,
335                             const char *account_name,
336                             const char *workstation)
337 {
338         init_lsa_String(&r->domain_name, domain_name);
339         r->parameter_control = parameter_control;
340         r->logon_id_low = logon_id_low;
341         r->logon_id_high = logon_id_high;
342         init_lsa_String(&r->account_name, account_name);
343         init_lsa_String(&r->workstation, workstation);
344 }
345
346 /*******************************************************************
347  inits a structure.
348  This is a network logon packet. The log_id parameters
349  are what an NT server would generate for LUID once the
350  user is logged on. I don't think we care about them.
351
352  Note that this has no access to the NT and LM hashed passwords,
353  so it forwards the challenge, and the NT and LM responses (24
354  bytes each) over the secure channel to the Domain controller
355  for it to say yea or nay. This is the preferred method of
356  checking for a logon as it doesn't export the password
357  hashes to anyone who has compromised the secure channel. JRA.
358
359 ********************************************************************/
360
361 void init_netr_NetworkInfo(struct netr_NetworkInfo *r,
362                            const char *domain_name,
363                            uint32_t parameter_control,
364                            uint32_t logon_id_low,
365                            uint32_t logon_id_high,
366                            const char *account_name,
367                            const char *workstation,
368                            uint8_t challenge[8],
369                            struct netr_ChallengeResponse nt,
370                            struct netr_ChallengeResponse lm)
371 {
372         init_netr_IdentityInfo(&r->identity_info,
373                                domain_name,
374                                parameter_control,
375                                logon_id_low,
376                                logon_id_high,
377                                account_name,
378                                workstation);
379         memcpy(r->challenge, challenge, 8);
380         r->nt = nt;
381         r->lm = lm;
382 }
383
384 /*******************************************************************
385  inits a structure.
386 ********************************************************************/
387
388 void init_netr_PasswordInfo(struct netr_PasswordInfo *r,
389                             const char *domain_name,
390                             uint32_t parameter_control,
391                             uint32_t logon_id_low,
392                             uint32_t logon_id_high,
393                             const char *account_name,
394                             const char *workstation,
395                             struct samr_Password lmpassword,
396                             struct samr_Password ntpassword)
397 {
398         init_netr_IdentityInfo(&r->identity_info,
399                                domain_name,
400                                parameter_control,
401                                logon_id_low,
402                                logon_id_high,
403                                account_name,
404                                workstation);
405         r->lmpassword = lmpassword;
406         r->ntpassword = ntpassword;
407 }
408
409 /*************************************************************************
410  inits a netr_CryptPassword structure
411  *************************************************************************/
412
413 void init_netr_CryptPassword(const char *pwd,
414                              unsigned char session_key[16],
415                              struct netr_CryptPassword *pwd_buf)
416 {
417         struct samr_CryptPassword password_buf;
418
419         encode_pw_buffer(password_buf.data, pwd, STR_UNICODE);
420
421         SamOEMhash(password_buf.data, session_key, 516);
422         memcpy(pwd_buf->data, password_buf.data, 512);
423         pwd_buf->length = IVAL(password_buf.data, 512);
424 }