s3-lsa: implement _lsa_EnumAccountsWithUserRight().
[ira/wip.git] / source3 / rpc_server / srv_wkssvc_nt.c
1 /* 
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *
5  *  Copyright (C) Andrew Tridgell               1992-1997,
6  *  Copyright (C) Gerald (Jerry) Carter         2006.
7  *  Copyright (C) Guenther Deschner             2007-2008.
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 3 of the License, or
12  *  (at your option) any later version.
13  *  
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *  
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22
23 /* This is the implementation of the wks interface. */
24
25 #include "includes.h"
26 #include "libnet/libnet.h"
27 #include "../libcli/auth/libcli_auth.h"
28
29 #undef DBGC_CLASS
30 #define DBGC_CLASS DBGC_RPC_SRV
31
32 /*******************************************************************
33  Fill in the values for the struct wkssvc_NetWkstaInfo100.
34  ********************************************************************/
35
36 static void create_wks_info_100(struct wkssvc_NetWkstaInfo100 *info100)
37 {
38         info100->platform_id     = PLATFORM_ID_NT;      /* unknown */
39         info100->version_major   = lp_major_announce_version();
40         info100->version_minor   = lp_minor_announce_version();
41
42         info100->server_name = talloc_asprintf_strupper_m(
43                 info100, "%s", global_myname());
44         info100->domain_name = talloc_asprintf_strupper_m(
45                 info100, "%s", lp_workgroup());
46
47         return;
48 }
49
50 /********************************************************************
51  only supports info level 100 at the moment.
52  ********************************************************************/
53
54 WERROR _wkssvc_NetWkstaGetInfo(pipes_struct *p, struct wkssvc_NetWkstaGetInfo *r)
55 {
56         struct wkssvc_NetWkstaInfo100 *wks100 = NULL;
57         
58         /* We only support info level 100 currently */
59         
60         if ( r->in.level != 100 ) {
61                 return WERR_UNKNOWN_LEVEL;
62         }
63
64         if ( (wks100 = TALLOC_ZERO_P(p->mem_ctx, struct wkssvc_NetWkstaInfo100)) == NULL ) {
65                 return WERR_NOMEM;
66         }
67
68         create_wks_info_100( wks100 );
69         
70         r->out.info->info100 = wks100;
71
72         return WERR_OK;
73 }
74
75 /********************************************************************
76  ********************************************************************/
77
78 WERROR _wkssvc_NetWkstaSetInfo(pipes_struct *p, struct wkssvc_NetWkstaSetInfo *r)
79 {
80         /* FIXME: Add implementation code here */
81         p->rng_fault_state = True;
82         return WERR_NOT_SUPPORTED;
83 }
84
85 /********************************************************************
86  ********************************************************************/
87
88 WERROR _wkssvc_NetWkstaEnumUsers(pipes_struct *p, struct wkssvc_NetWkstaEnumUsers *r)
89 {
90         /* FIXME: Add implementation code here */
91         p->rng_fault_state = True;
92         return WERR_NOT_SUPPORTED;
93 }
94
95 /********************************************************************
96  ********************************************************************/
97
98 WERROR _wkssvc_NetrWkstaUserGetInfo(pipes_struct *p, struct wkssvc_NetrWkstaUserGetInfo *r)
99 {
100         /* FIXME: Add implementation code here */
101         p->rng_fault_state = True;
102         return WERR_NOT_SUPPORTED;
103 }
104
105 /********************************************************************
106  ********************************************************************/
107
108 WERROR _wkssvc_NetrWkstaUserSetInfo(pipes_struct *p, struct wkssvc_NetrWkstaUserSetInfo *r)
109 {
110         /* FIXME: Add implementation code here */
111         p->rng_fault_state = True;
112         return WERR_NOT_SUPPORTED;
113 }
114
115 /********************************************************************
116  ********************************************************************/
117
118 WERROR _wkssvc_NetWkstaTransportEnum(pipes_struct *p, struct wkssvc_NetWkstaTransportEnum *r)
119 {
120         /* FIXME: Add implementation code here */
121         p->rng_fault_state = True;
122         return WERR_NOT_SUPPORTED;
123 }
124
125 /********************************************************************
126  ********************************************************************/
127
128 WERROR _wkssvc_NetrWkstaTransportAdd(pipes_struct *p, struct wkssvc_NetrWkstaTransportAdd *r)
129 {
130         /* FIXME: Add implementation code here */
131         p->rng_fault_state = True;
132         return WERR_NOT_SUPPORTED;
133 }
134
135 /********************************************************************
136  ********************************************************************/
137
138 WERROR _wkssvc_NetrWkstaTransportDel(pipes_struct *p, struct wkssvc_NetrWkstaTransportDel *r)
139 {
140         /* FIXME: Add implementation code here */
141         p->rng_fault_state = True;
142         return WERR_NOT_SUPPORTED;
143 }
144
145 /********************************************************************
146  ********************************************************************/
147
148 WERROR _wkssvc_NetrUseAdd(pipes_struct *p, struct wkssvc_NetrUseAdd *r)
149 {
150         /* FIXME: Add implementation code here */
151         p->rng_fault_state = True;
152         return WERR_NOT_SUPPORTED;
153 }
154
155 /********************************************************************
156  ********************************************************************/
157
158 WERROR _wkssvc_NetrUseGetInfo(pipes_struct *p, struct wkssvc_NetrUseGetInfo *r)
159 {
160         /* FIXME: Add implementation code here */
161         p->rng_fault_state = True;
162         return WERR_NOT_SUPPORTED;
163 }
164
165 /********************************************************************
166  ********************************************************************/
167
168 WERROR _wkssvc_NetrUseDel(pipes_struct *p, struct wkssvc_NetrUseDel *r)
169 {
170         /* FIXME: Add implementation code here */
171         p->rng_fault_state = True;
172         return WERR_NOT_SUPPORTED;
173 }
174
175 /********************************************************************
176  ********************************************************************/
177
178 WERROR _wkssvc_NetrUseEnum(pipes_struct *p, struct wkssvc_NetrUseEnum *r)
179 {
180         /* FIXME: Add implementation code here */
181         p->rng_fault_state = True;
182         return WERR_NOT_SUPPORTED;
183 }
184
185 /********************************************************************
186  ********************************************************************/
187
188 WERROR _wkssvc_NetrMessageBufferSend(pipes_struct *p, struct wkssvc_NetrMessageBufferSend *r)
189 {
190         /* FIXME: Add implementation code here */
191         p->rng_fault_state = True;
192         return WERR_NOT_SUPPORTED;
193 }
194
195 /********************************************************************
196  ********************************************************************/
197
198 WERROR _wkssvc_NetrWorkstationStatisticsGet(pipes_struct *p, struct wkssvc_NetrWorkstationStatisticsGet *r) 
199 {
200         /* FIXME: Add implementation code here */
201         p->rng_fault_state = True;
202         return WERR_NOT_SUPPORTED;
203 }
204
205 /********************************************************************
206  ********************************************************************/
207
208 WERROR _wkssvc_NetrLogonDomainNameAdd(pipes_struct *p, struct wkssvc_NetrLogonDomainNameAdd *r)
209 {
210         /* FIXME: Add implementation code here */
211         p->rng_fault_state = True;
212         return WERR_NOT_SUPPORTED;
213 }
214
215 /********************************************************************
216  ********************************************************************/
217
218 WERROR _wkssvc_NetrLogonDomainNameDel(pipes_struct *p, struct wkssvc_NetrLogonDomainNameDel *r)
219 {
220         /* FIXME: Add implementation code here */
221         p->rng_fault_state = True;
222         return WERR_NOT_SUPPORTED;
223 }
224
225 /********************************************************************
226  ********************************************************************/
227
228 WERROR _wkssvc_NetrJoinDomain(pipes_struct *p, struct wkssvc_NetrJoinDomain *r)
229 {
230         /* FIXME: Add implementation code here */
231         p->rng_fault_state = True;
232         return WERR_NOT_SUPPORTED;
233 }
234
235 /********************************************************************
236  ********************************************************************/
237
238 WERROR _wkssvc_NetrUnjoinDomain(pipes_struct *p, struct wkssvc_NetrUnjoinDomain *r)
239 {
240         /* FIXME: Add implementation code here */
241         p->rng_fault_state = True;
242         return WERR_NOT_SUPPORTED;
243 }
244
245 /********************************************************************
246  ********************************************************************/
247
248 WERROR _wkssvc_NetrRenameMachineInDomain(pipes_struct *p, struct wkssvc_NetrRenameMachineInDomain *r)
249 {
250         /* FIXME: Add implementation code here */
251         p->rng_fault_state = True;
252         return WERR_NOT_SUPPORTED;
253 }
254
255 /********************************************************************
256  ********************************************************************/
257
258 WERROR _wkssvc_NetrValidateName(pipes_struct *p, struct wkssvc_NetrValidateName *r)
259 {
260         /* FIXME: Add implementation code here */
261         p->rng_fault_state = True;
262         return WERR_NOT_SUPPORTED;
263 }
264
265 /********************************************************************
266  ********************************************************************/
267
268 WERROR _wkssvc_NetrGetJoinInformation(pipes_struct *p, struct wkssvc_NetrGetJoinInformation *r)
269 {
270         /* FIXME: Add implementation code here */
271         p->rng_fault_state = True;
272         return WERR_NOT_SUPPORTED;
273 }
274
275 /********************************************************************
276  ********************************************************************/
277
278 WERROR _wkssvc_NetrGetJoinableOus(pipes_struct *p, struct wkssvc_NetrGetJoinableOus *r)
279 {
280         /* FIXME: Add implementation code here */
281         p->rng_fault_state = True;
282         return WERR_NOT_SUPPORTED;
283 }
284
285 /********************************************************************
286  _wkssvc_NetrJoinDomain2
287  ********************************************************************/
288
289 WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p,
290                                struct wkssvc_NetrJoinDomain2 *r)
291 {
292         struct libnet_JoinCtx *j = NULL;
293         char *cleartext_pwd = NULL;
294         char *admin_domain = NULL;
295         char *admin_account = NULL;
296         WERROR werr;
297         struct nt_user_token *token = p->server_info->ptok;
298
299         if (!r->in.domain_name) {
300                 return WERR_INVALID_PARAM;
301         }
302
303         if (!r->in.admin_account || !r->in.encrypted_password) {
304                 return WERR_INVALID_PARAM;
305         }
306
307         if (!user_has_privileges(token, &se_machine_account) &&
308             !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) &&
309             !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) {
310                 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
311                         "sufficient privileges\n"));
312                 return WERR_ACCESS_DENIED;
313         }
314
315         if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) ||
316             (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
317                 return WERR_NOT_SUPPORTED;
318         }
319
320         werr = decode_wkssvc_join_password_buffer(
321                 p->mem_ctx, r->in.encrypted_password,
322                 &p->server_info->user_session_key, &cleartext_pwd);
323         if (!W_ERROR_IS_OK(werr)) {
324                 return werr;
325         }
326
327         split_domain_user(p->mem_ctx,
328                           r->in.admin_account,
329                           &admin_domain,
330                           &admin_account);
331
332         werr = libnet_init_JoinCtx(p->mem_ctx, &j);
333         if (!W_ERROR_IS_OK(werr)) {
334                 return werr;
335         }
336
337         j->in.domain_name       = r->in.domain_name;
338         j->in.account_ou        = r->in.account_ou;
339         j->in.join_flags        = r->in.join_flags;
340         j->in.admin_account     = admin_account;
341         j->in.admin_password    = cleartext_pwd;
342         j->in.debug             = true;
343         j->in.modify_config     = lp_config_backend_is_registry();
344         j->in.msg_ctx           = smbd_messaging_context();
345
346         become_root();
347         werr = libnet_Join(p->mem_ctx, j);
348         unbecome_root();
349
350         if (!W_ERROR_IS_OK(werr)) {
351                 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
352                         j->out.error_string ? j->out.error_string :
353                         win_errstr(werr)));
354         }
355
356         TALLOC_FREE(j);
357         return werr;
358 }
359
360 /********************************************************************
361  _wkssvc_NetrUnjoinDomain2
362  ********************************************************************/
363
364 WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p,
365                                  struct wkssvc_NetrUnjoinDomain2 *r)
366 {
367         struct libnet_UnjoinCtx *u = NULL;
368         char *cleartext_pwd = NULL;
369         char *admin_domain = NULL;
370         char *admin_account = NULL;
371         WERROR werr;
372         struct nt_user_token *token = p->server_info->ptok;
373
374         if (!r->in.account || !r->in.encrypted_password) {
375                 return WERR_INVALID_PARAM;
376         }
377
378         if (!user_has_privileges(token, &se_machine_account) &&
379             !nt_token_check_domain_rid(token, DOMAIN_GROUP_RID_ADMINS) &&
380             !nt_token_check_domain_rid(token, BUILTIN_ALIAS_RID_ADMINS)) {
381                 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
382                         "sufficient privileges\n"));
383                 return WERR_ACCESS_DENIED;
384         }
385
386         werr = decode_wkssvc_join_password_buffer(
387                 p->mem_ctx, r->in.encrypted_password,
388                 &p->server_info->user_session_key, &cleartext_pwd);
389         if (!W_ERROR_IS_OK(werr)) {
390                 return werr;
391         }
392
393         split_domain_user(p->mem_ctx,
394                           r->in.account,
395                           &admin_domain,
396                           &admin_account);
397
398         werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
399         if (!W_ERROR_IS_OK(werr)) {
400                 return werr;
401         }
402
403         u->in.domain_name       = lp_realm();
404         u->in.unjoin_flags      = r->in.unjoin_flags |
405                                   WKSSVC_JOIN_FLAGS_JOIN_TYPE;
406         u->in.admin_account     = admin_account;
407         u->in.admin_password    = cleartext_pwd;
408         u->in.debug             = true;
409         u->in.modify_config     = lp_config_backend_is_registry();
410         u->in.msg_ctx           = smbd_messaging_context();
411
412         become_root();
413         werr = libnet_Unjoin(p->mem_ctx, u);
414         unbecome_root();
415
416         if (!W_ERROR_IS_OK(werr)) {
417                 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
418                         u->out.error_string ? u->out.error_string :
419                         win_errstr(werr)));
420         }
421
422         TALLOC_FREE(u);
423         return werr;
424 }
425
426 /********************************************************************
427  ********************************************************************/
428
429 WERROR _wkssvc_NetrRenameMachineInDomain2(pipes_struct *p, struct wkssvc_NetrRenameMachineInDomain2 *r)
430 {
431         /* for now just return not supported */
432         return WERR_NOT_SUPPORTED;
433 }
434
435 /********************************************************************
436  ********************************************************************/
437
438 WERROR _wkssvc_NetrValidateName2(pipes_struct *p, struct wkssvc_NetrValidateName2 *r)
439 {
440         /* FIXME: Add implementation code here */
441         p->rng_fault_state = True;
442         return WERR_NOT_SUPPORTED;
443 }
444
445 /********************************************************************
446  ********************************************************************/
447
448 WERROR _wkssvc_NetrGetJoinableOus2(pipes_struct *p, struct wkssvc_NetrGetJoinableOus2 *r)
449 {
450         /* FIXME: Add implementation code here */
451         p->rng_fault_state = True;
452         return WERR_NOT_SUPPORTED;
453 }
454
455 /********************************************************************
456  ********************************************************************/
457
458 WERROR _wkssvc_NetrAddAlternateComputerName(pipes_struct *p, struct wkssvc_NetrAddAlternateComputerName *r)
459 {
460         /* FIXME: Add implementation code here */
461         p->rng_fault_state = True;
462         return WERR_NOT_SUPPORTED;
463 }
464
465 /********************************************************************
466  ********************************************************************/
467
468 WERROR _wkssvc_NetrRemoveAlternateComputerName(pipes_struct *p, struct wkssvc_NetrRemoveAlternateComputerName *r)
469 {
470         /* FIXME: Add implementation code here */
471         p->rng_fault_state = True;
472         return WERR_NOT_SUPPORTED;
473 }
474
475 /********************************************************************
476  ********************************************************************/
477
478 WERROR _wkssvc_NetrSetPrimaryComputername(pipes_struct *p, struct wkssvc_NetrSetPrimaryComputername *r)
479 {
480         /* FIXME: Add implementation code here */
481         p->rng_fault_state = True;
482         return WERR_NOT_SUPPORTED;
483 }
484
485 /********************************************************************
486  ********************************************************************/
487
488 WERROR _wkssvc_NetrEnumerateComputerNames(pipes_struct *p, struct wkssvc_NetrEnumerateComputerNames *r)
489 {
490         /* FIXME: Add implementation code here */
491         p->rng_fault_state = True;
492         return WERR_NOT_SUPPORTED;
493 }
494