s3:libsmb: let cli_read_andx_create() accept any length
[Samba/gebeck_regimport.git] / source3 / rpc_server / wkssvc / srv_wkssvc_nt.c
blobc06bfc97d60b2d84512c3d38a039f46d51534567
1 /*
2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1997,
6 * Copyright (C) Gerald (Jerry) Carter 2006.
7 * Copyright (C) Guenther Deschner 2007-2008.
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.
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.
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/>.
23 /* This is the implementation of the wks interface. */
25 #include "includes.h"
26 #include "ntdomain.h"
27 #include "librpc/gen_ndr/libnet_join.h"
28 #include "libnet/libnet_join.h"
29 #include "../libcli/auth/libcli_auth.h"
30 #include "../librpc/gen_ndr/srv_wkssvc.h"
31 #include "../libcli/security/security.h"
32 #include "session.h"
33 #include "smbd/smbd.h"
34 #include "auth.h"
35 #include "krb5_env.h"
37 #undef DBGC_CLASS
38 #define DBGC_CLASS DBGC_RPC_SRV
40 struct dom_usr {
41 char *name;
42 char *domain;
43 time_t login_time;
46 #ifdef HAVE_GETUTXENT
48 #include <utmpx.h>
50 struct usrinfo {
51 char *name;
52 struct timeval login_time;
55 static int usr_info_cmp(const struct usrinfo *usr1, const struct usrinfo *usr2)
57 /* Called from qsort to compare two users in a usrinfo_t array for
58 * sorting by login time. Return >0 if usr1 login time was later than
59 * usr2 login time, <0 if it was earlier */
60 return timeval_compare(&usr1->login_time, &usr2->login_time);
63 /*******************************************************************
64 Get a list of the names of all users logged into this machine
65 ********************************************************************/
67 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
69 char **users;
70 int i, num_users = 0;
71 struct usrinfo *usr_infos = NULL;
72 struct utmpx *u;
74 while ((u = getutxent()) != NULL) {
75 struct usrinfo *tmp;
76 if (u->ut_type != USER_PROCESS) {
77 continue;
79 for (i = 0; i < num_users; i++) {
80 /* getutxent can return multiple user entries for the
81 * same user, so ignore any dups */
82 if (strcmp(u->ut_user, usr_infos[i].name) == 0) {
83 break;
86 if (i < num_users) {
87 continue;
90 tmp = talloc_realloc(mem_ctx, usr_infos, struct usrinfo,
91 num_users+1);
92 if (tmp == NULL) {
93 TALLOC_FREE(tmp);
94 endutxent();
95 return NULL;
97 usr_infos = tmp;
98 usr_infos[num_users].name = talloc_strdup(usr_infos,
99 u->ut_user);
100 if (usr_infos[num_users].name == NULL) {
101 TALLOC_FREE(usr_infos);
102 endutxent();
103 return NULL;
105 usr_infos[num_users].login_time.tv_sec = u->ut_tv.tv_sec;
106 usr_infos[num_users].login_time.tv_usec = u->ut_tv.tv_usec;
107 num_users += 1;
110 /* Sort the user list by time, oldest first */
111 TYPESAFE_QSORT(usr_infos, num_users, usr_info_cmp);
113 users = (char**)talloc_array(mem_ctx, char*, num_users);
114 if (users) {
115 for (i = 0; i < num_users; i++) {
116 users[i] = talloc_move(users, &usr_infos[i].name);
119 TALLOC_FREE(usr_infos);
120 endutxent();
121 errno = 0;
122 return users;
125 #else
127 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
129 return NULL;
132 #endif
134 static int dom_user_cmp(const struct dom_usr *usr1, const struct dom_usr *usr2)
136 /* Called from qsort to compare two domain users in a dom_usr_t array
137 * for sorting by login time. Return >0 if usr1 login time was later
138 * than usr2 login time, <0 if it was earlier */
139 return (usr1->login_time - usr2->login_time);
142 /*******************************************************************
143 Get a list of the names of all users of this machine who are
144 logged into the domain.
146 This should return a list of the users on this machine who are
147 logged into the domain (i.e. have been authenticated by the domain's
148 password server) but that doesn't fit well with the normal Samba
149 scenario where accesses out to the domain are made through smbclient
150 with each such session individually authenticated. So about the best
151 we can do currently is to list sessions of local users connected to
152 this server, which means that to get themself included in the list a
153 local user must create a session to the local samba server by running:
154 smbclient \\\\localhost\\share
156 FIXME: find a better way to get local users logged into the domain
157 in this list.
158 ********************************************************************/
160 static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx)
162 struct sessionid *session_list = NULL;
163 char *machine_name, *p, *nm;
164 const char *sep;
165 struct dom_usr *users, *tmp;
166 int i, num_users, num_sessions;
168 sep = lp_winbind_separator();
169 if (!sep) {
170 sep = "\\";
173 num_sessions = list_sessions(mem_ctx, &session_list);
174 if (num_sessions == 0) {
175 errno = 0;
176 return NULL;
179 users = talloc_array(mem_ctx, struct dom_usr, num_sessions);
180 if (users == NULL) {
181 TALLOC_FREE(session_list);
182 return NULL;
185 for (i=num_users=0; i<num_sessions; i++) {
186 if (session_list[i].username[0] == '\0' ||
187 session_list[i].remote_machine[0] == '\0') {
188 continue;
190 p = strpbrk(session_list[i].remote_machine, "./");
191 if (p) {
192 *p = '\0';
194 machine_name = talloc_asprintf_strupper_m(
195 users, "%s", session_list[i].remote_machine);
196 if (machine_name == NULL) {
197 DEBUG(10, ("talloc_asprintf failed\n"));
198 continue;
200 if (strcmp(machine_name, lp_netbios_name()) == 0) {
201 p = session_list[i].username;
202 nm = strstr(p, sep);
203 if (nm) {
205 * "domain+name" format so split domain and
206 * name components
208 *nm = '\0';
209 nm += strlen(sep);
210 users[num_users].domain =
211 talloc_asprintf_strupper_m(users,
212 "%s", p);
213 users[num_users].name = talloc_strdup(users,
214 nm);
215 } else {
217 * Simple user name so get domain from smb.conf
219 users[num_users].domain =
220 talloc_strdup(users, lp_workgroup());
221 users[num_users].name = talloc_strdup(users,
224 users[num_users].login_time =
225 session_list[i].connect_start;
226 num_users++;
228 TALLOC_FREE(machine_name);
230 TALLOC_FREE(session_list);
232 tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users);
233 if (tmp == NULL) {
234 return NULL;
236 users = tmp;
238 /* Sort the user list by time, oldest first */
239 TYPESAFE_QSORT(users, num_users, dom_user_cmp);
241 errno = 0;
242 return users;
245 /*******************************************************************
246 RPC Workstation Service request NetWkstaGetInfo with level 100.
247 Returns to the requester:
248 - The machine name.
249 - The smb version number
250 - The domain name.
251 Returns a filled in wkssvc_NetWkstaInfo100 struct.
252 ********************************************************************/
254 static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx)
256 struct wkssvc_NetWkstaInfo100 *info100;
258 info100 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo100);
259 if (info100 == NULL) {
260 return NULL;
263 info100->platform_id = PLATFORM_ID_NT; /* unknown */
264 info100->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
265 info100->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
267 info100->server_name = talloc_asprintf_strupper_m(
268 info100, "%s", lp_netbios_name());
269 info100->domain_name = talloc_asprintf_strupper_m(
270 info100, "%s", lp_workgroup());
272 return info100;
275 /*******************************************************************
276 RPC Workstation Service request NetWkstaGetInfo with level 101.
277 Returns to the requester:
278 - As per NetWkstaGetInfo with level 100, plus:
279 - The LANMAN directory path (not currently supported).
280 Returns a filled in wkssvc_NetWkstaInfo101 struct.
281 ********************************************************************/
283 static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx)
285 struct wkssvc_NetWkstaInfo101 *info101;
287 info101 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo101);
288 if (info101 == NULL) {
289 return NULL;
292 info101->platform_id = PLATFORM_ID_NT; /* unknown */
293 info101->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
294 info101->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
296 info101->server_name = talloc_asprintf_strupper_m(
297 info101, "%s", lp_netbios_name());
298 info101->domain_name = talloc_asprintf_strupper_m(
299 info101, "%s", lp_workgroup());
300 info101->lan_root = "";
302 return info101;
305 /*******************************************************************
306 RPC Workstation Service request NetWkstaGetInfo with level 102.
307 Returns to the requester:
308 - As per NetWkstaGetInfo with level 101, plus:
309 - The number of logged in users.
310 Returns a filled in wkssvc_NetWkstaInfo102 struct.
311 ********************************************************************/
313 static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
315 struct wkssvc_NetWkstaInfo102 *info102;
316 char **users;
318 info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
319 if (info102 == NULL) {
320 return NULL;
323 info102->platform_id = PLATFORM_ID_NT; /* unknown */
324 info102->version_major = SAMBA_MAJOR_NBT_ANNOUNCE_VERSION;
325 info102->version_minor = SAMBA_MINOR_NBT_ANNOUNCE_VERSION;
327 info102->server_name = talloc_asprintf_strupper_m(
328 info102, "%s", lp_netbios_name());
329 info102->domain_name = talloc_asprintf_strupper_m(
330 info102, "%s", lp_workgroup());
331 info102->lan_root = "";
333 users = get_logged_on_userlist(talloc_tos());
334 info102->logged_on_users = talloc_array_length(users);
336 TALLOC_FREE(users);
338 return info102;
341 /********************************************************************
342 Handling for RPC Workstation Service request NetWkstaGetInfo
343 ********************************************************************/
345 WERROR _wkssvc_NetWkstaGetInfo(struct pipes_struct *p,
346 struct wkssvc_NetWkstaGetInfo *r)
348 switch (r->in.level) {
349 case 100:
350 /* Level 100 can be allowed from anyone including anonymous
351 * so no access checks are needed for this case */
352 r->out.info->info100 = create_wks_info_100(p->mem_ctx);
353 if (r->out.info->info100 == NULL) {
354 return WERR_NOMEM;
356 break;
357 case 101:
358 /* Level 101 can be allowed from any logged in user */
359 if (!nt_token_check_sid(&global_sid_Authenticated_Users,
360 p->session_info->security_token)) {
361 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
362 "101\n"));
363 DEBUGADD(3,(" - does not have sid for Authenticated "
364 "Users %s:\n",
365 sid_string_dbg(
366 &global_sid_Authenticated_Users)));
367 security_token_debug(DBGC_CLASS, 3,
368 p->session_info->security_token);
369 return WERR_ACCESS_DENIED;
371 r->out.info->info101 = create_wks_info_101(p->mem_ctx);
372 if (r->out.info->info101 == NULL) {
373 return WERR_NOMEM;
375 break;
376 case 102:
377 /* Level 102 Should only be allowed from a domain administrator */
378 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
379 p->session_info->security_token)) {
380 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
381 "102\n"));
382 DEBUGADD(3,(" - does not have sid for Administrators "
383 "group %s, sids are:\n",
384 sid_string_dbg(&global_sid_Builtin_Administrators)));
385 security_token_debug(DBGC_CLASS, 3,
386 p->session_info->security_token);
387 return WERR_ACCESS_DENIED;
389 r->out.info->info102 = create_wks_info_102(p->mem_ctx);
390 if (r->out.info->info102 == NULL) {
391 return WERR_NOMEM;
393 break;
394 default:
395 return WERR_UNKNOWN_LEVEL;
398 return WERR_OK;
401 /********************************************************************
402 ********************************************************************/
404 WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
405 struct wkssvc_NetWkstaSetInfo *r)
407 /* FIXME: Add implementation code here */
408 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
409 return WERR_NOT_SUPPORTED;
412 /********************************************************************
413 RPC Workstation Service request NetWkstaEnumUsers with level 0:
414 Returns to the requester:
415 - the user names of the logged in users.
416 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
417 ********************************************************************/
419 static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0(
420 TALLOC_CTX *mem_ctx)
422 struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0;
423 char **users;
424 int i, num_users;
426 ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0);
427 if (ctr0 == NULL) {
428 return NULL;
431 users = get_logged_on_userlist(talloc_tos());
432 if (users == NULL && errno != 0) {
433 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
434 errno, strerror(errno)));
435 TALLOC_FREE(ctr0);
436 return NULL;
439 num_users = talloc_array_length(users);
440 ctr0->entries_read = num_users;
441 ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0,
442 num_users);
443 if (ctr0->user0 == NULL) {
444 TALLOC_FREE(ctr0);
445 TALLOC_FREE(users);
446 return NULL;
449 for (i=0; i<num_users; i++) {
450 ctr0->user0[i].user_name = talloc_move(ctr0->user0, &users[i]);
452 TALLOC_FREE(users);
453 return ctr0;
456 /********************************************************************
457 RPC Workstation Service request NetWkstaEnumUsers with level 1.
458 Returns to the requester:
459 - the user names of the logged in users,
460 - the domain or machine each is logged into,
461 - the password server that was used to authenticate each,
462 - other domains each user is logged into (not currently supported).
463 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
464 ********************************************************************/
466 static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1(
467 TALLOC_CTX *mem_ctx)
469 struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1;
470 char **users;
471 struct dom_usr *dom_users;
472 const char *pwd_server;
473 char *pwd_tmp;
474 int i, j, num_users, num_dom_users;
476 ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1);
477 if (ctr1 == NULL) {
478 return NULL;
481 users = get_logged_on_userlist(talloc_tos());
482 if (users == NULL && errno != 0) {
483 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
484 errno, strerror(errno)));
485 TALLOC_FREE(ctr1);
486 return NULL;
488 num_users = talloc_array_length(users);
490 dom_users = get_domain_userlist(talloc_tos());
491 if (dom_users == NULL && errno != 0) {
492 TALLOC_FREE(ctr1);
493 TALLOC_FREE(users);
494 return NULL;
496 num_dom_users = talloc_array_length(dom_users);
498 ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1,
499 num_users+num_dom_users);
500 if (ctr1->user1 == NULL) {
501 TALLOC_FREE(ctr1);
502 TALLOC_FREE(users);
503 TALLOC_FREE(dom_users);
504 return NULL;
507 pwd_server = "";
509 if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_passwordserver()))) {
510 /* The configured password server is a full DNS name but
511 * for the logon server we need to return just the first
512 * component (machine name) of it in upper-case */
513 char *p = strchr(pwd_tmp, '.');
514 if (p) {
515 *p = '\0';
516 } else {
517 p = pwd_tmp + strlen(pwd_tmp);
519 while (--p >= pwd_tmp) {
520 *p = toupper(*p);
522 pwd_server = pwd_tmp;
525 /* Put in local users first */
526 for (i=0; i<num_users; i++) {
527 ctr1->user1[i].user_name = talloc_move(ctr1->user1, &users[i]);
529 /* For a local user the domain name and logon server are
530 * both returned as the local machine's NetBIOS name */
531 ctr1->user1[i].logon_domain = ctr1->user1[i].logon_server =
532 talloc_asprintf_strupper_m(ctr1->user1, "%s", lp_netbios_name());
534 ctr1->user1[i].other_domains = NULL; /* Maybe in future? */
537 /* Now domain users */
538 for (j=0; j<num_dom_users; j++) {
539 ctr1->user1[i].user_name =
540 talloc_strdup(ctr1->user1, dom_users[j].name);
541 ctr1->user1[i].logon_domain =
542 talloc_strdup(ctr1->user1, dom_users[j].domain);
543 ctr1->user1[i].logon_server = pwd_server;
545 ctr1->user1[i++].other_domains = NULL; /* Maybe in future? */
548 ctr1->entries_read = i;
550 TALLOC_FREE(users);
551 TALLOC_FREE(dom_users);
552 return ctr1;
555 /********************************************************************
556 Handling for RPC Workstation Service request NetWkstaEnumUsers
557 (a.k.a Windows NetWkstaUserEnum)
558 ********************************************************************/
560 WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
561 struct wkssvc_NetWkstaEnumUsers *r)
563 /* This with any level should only be allowed from a domain administrator */
564 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
565 p->session_info->security_token)) {
566 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
567 DEBUGADD(3,(" - does not have sid for Administrators group "
568 "%s\n", sid_string_dbg(
569 &global_sid_Builtin_Administrators)));
570 security_token_debug(DBGC_CLASS, 3, p->session_info->security_token);
571 return WERR_ACCESS_DENIED;
574 switch (r->in.info->level) {
575 case 0:
576 r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
577 if (r->out.info->ctr.user0 == NULL) {
578 return WERR_NOMEM;
580 r->out.info->level = r->in.info->level;
581 *r->out.entries_read = r->out.info->ctr.user0->entries_read;
582 if (r->out.resume_handle != NULL) {
583 *r->out.resume_handle = 0;
585 break;
586 case 1:
587 r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
588 if (r->out.info->ctr.user1 == NULL) {
589 return WERR_NOMEM;
591 r->out.info->level = r->in.info->level;
592 *r->out.entries_read = r->out.info->ctr.user1->entries_read;
593 if (r->out.resume_handle != NULL) {
594 *r->out.resume_handle = 0;
596 break;
597 default:
598 return WERR_UNKNOWN_LEVEL;
601 return WERR_OK;
604 /********************************************************************
605 ********************************************************************/
607 WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
608 struct wkssvc_NetrWkstaUserGetInfo *r)
610 /* FIXME: Add implementation code here */
611 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
612 return WERR_NOT_SUPPORTED;
615 /********************************************************************
616 ********************************************************************/
618 WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
619 struct wkssvc_NetrWkstaUserSetInfo *r)
621 /* FIXME: Add implementation code here */
622 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
623 return WERR_NOT_SUPPORTED;
626 /********************************************************************
627 ********************************************************************/
629 WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
630 struct wkssvc_NetWkstaTransportEnum *r)
632 /* FIXME: Add implementation code here */
633 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
634 return WERR_NOT_SUPPORTED;
637 /********************************************************************
638 ********************************************************************/
640 WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
641 struct wkssvc_NetrWkstaTransportAdd *r)
643 /* FIXME: Add implementation code here */
644 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
645 return WERR_NOT_SUPPORTED;
648 /********************************************************************
649 ********************************************************************/
651 WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
652 struct wkssvc_NetrWkstaTransportDel *r)
654 /* FIXME: Add implementation code here */
655 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
656 return WERR_NOT_SUPPORTED;
659 /********************************************************************
660 ********************************************************************/
662 WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
663 struct wkssvc_NetrUseAdd *r)
665 /* FIXME: Add implementation code here */
666 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
667 return WERR_NOT_SUPPORTED;
670 /********************************************************************
671 ********************************************************************/
673 WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
674 struct wkssvc_NetrUseGetInfo *r)
676 /* FIXME: Add implementation code here */
677 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
678 return WERR_NOT_SUPPORTED;
681 /********************************************************************
682 ********************************************************************/
684 WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
685 struct wkssvc_NetrUseDel *r)
687 /* FIXME: Add implementation code here */
688 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
689 return WERR_NOT_SUPPORTED;
692 /********************************************************************
693 ********************************************************************/
695 WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
696 struct wkssvc_NetrUseEnum *r)
698 /* FIXME: Add implementation code here */
699 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
700 return WERR_NOT_SUPPORTED;
703 /********************************************************************
704 ********************************************************************/
706 WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
707 struct wkssvc_NetrMessageBufferSend *r)
709 /* FIXME: Add implementation code here */
710 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
711 return WERR_NOT_SUPPORTED;
714 /********************************************************************
715 ********************************************************************/
717 WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
718 struct wkssvc_NetrWorkstationStatisticsGet *r)
720 /* FIXME: Add implementation code here */
721 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
722 return WERR_NOT_SUPPORTED;
725 /********************************************************************
726 ********************************************************************/
728 WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
729 struct wkssvc_NetrLogonDomainNameAdd *r)
731 /* FIXME: Add implementation code here */
732 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
733 return WERR_NOT_SUPPORTED;
736 /********************************************************************
737 ********************************************************************/
739 WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
740 struct wkssvc_NetrLogonDomainNameDel *r)
742 /* FIXME: Add implementation code here */
743 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
744 return WERR_NOT_SUPPORTED;
747 /********************************************************************
748 ********************************************************************/
750 WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
751 struct wkssvc_NetrJoinDomain *r)
753 /* FIXME: Add implementation code here */
754 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
755 return WERR_NOT_SUPPORTED;
758 /********************************************************************
759 ********************************************************************/
761 WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
762 struct wkssvc_NetrUnjoinDomain *r)
764 /* FIXME: Add implementation code here */
765 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
766 return WERR_NOT_SUPPORTED;
769 /********************************************************************
770 ********************************************************************/
772 WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
773 struct wkssvc_NetrRenameMachineInDomain *r)
775 /* FIXME: Add implementation code here */
776 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
777 return WERR_NOT_SUPPORTED;
780 /********************************************************************
781 ********************************************************************/
783 WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
784 struct wkssvc_NetrValidateName *r)
786 /* FIXME: Add implementation code here */
787 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
788 return WERR_NOT_SUPPORTED;
791 /********************************************************************
792 ********************************************************************/
794 WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
795 struct wkssvc_NetrGetJoinInformation *r)
797 /* FIXME: Add implementation code here */
798 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
799 return WERR_NOT_SUPPORTED;
802 /********************************************************************
803 ********************************************************************/
805 WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
806 struct wkssvc_NetrGetJoinableOus *r)
808 /* FIXME: Add implementation code here */
809 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
810 return WERR_NOT_SUPPORTED;
813 /********************************************************************
814 _wkssvc_NetrJoinDomain2
815 ********************************************************************/
817 WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
818 struct wkssvc_NetrJoinDomain2 *r)
820 struct libnet_JoinCtx *j = NULL;
821 char *cleartext_pwd = NULL;
822 char *admin_domain = NULL;
823 char *admin_account = NULL;
824 WERROR werr;
825 struct security_token *token = p->session_info->security_token;
826 NTSTATUS status;
827 DATA_BLOB session_key;
829 if (!r->in.domain_name) {
830 return WERR_INVALID_PARAM;
833 if (!r->in.admin_account || !r->in.encrypted_password) {
834 return WERR_INVALID_PARAM;
837 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
838 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
839 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
840 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
841 "sufficient privileges\n"));
842 return WERR_ACCESS_DENIED;
845 if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) ||
846 (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
847 return WERR_NOT_SUPPORTED;
850 status = session_extract_session_key(p->session_info,
851 &session_key,
852 KEY_USE_16BYTES);
853 if(!NT_STATUS_IS_OK(status)) {
854 DEBUG(5,("_wkssvc_NetrJoinDomain2: no session key %s\n",
855 nt_errstr(status)));
856 return WERR_NO_USER_SESSION_KEY;
859 werr = decode_wkssvc_join_password_buffer(
860 p->mem_ctx, r->in.encrypted_password,
861 &session_key, &cleartext_pwd);
862 if (!W_ERROR_IS_OK(werr)) {
863 return werr;
866 split_domain_user(p->mem_ctx,
867 r->in.admin_account,
868 &admin_domain,
869 &admin_account);
871 werr = libnet_init_JoinCtx(p->mem_ctx, &j);
872 if (!W_ERROR_IS_OK(werr)) {
873 return werr;
876 j->in.domain_name = r->in.domain_name;
877 j->in.account_ou = r->in.account_ou;
878 j->in.join_flags = r->in.join_flags;
879 j->in.admin_account = admin_account;
880 j->in.admin_password = cleartext_pwd;
881 j->in.debug = true;
882 j->in.modify_config = lp_config_backend_is_registry();
883 j->in.msg_ctx = p->msg_ctx;
885 become_root();
886 setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrJoinDomain2", 1);
887 werr = libnet_Join(p->mem_ctx, j);
888 unsetenv(KRB5_ENV_CCNAME);
889 unbecome_root();
891 if (!W_ERROR_IS_OK(werr)) {
892 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
893 j->out.error_string ? j->out.error_string :
894 win_errstr(werr)));
897 TALLOC_FREE(j);
898 return werr;
901 /********************************************************************
902 _wkssvc_NetrUnjoinDomain2
903 ********************************************************************/
905 WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
906 struct wkssvc_NetrUnjoinDomain2 *r)
908 struct libnet_UnjoinCtx *u = NULL;
909 char *cleartext_pwd = NULL;
910 char *admin_domain = NULL;
911 char *admin_account = NULL;
912 WERROR werr;
913 struct security_token *token = p->session_info->security_token;
914 NTSTATUS status;
915 DATA_BLOB session_key;
917 if (!r->in.account || !r->in.encrypted_password) {
918 return WERR_INVALID_PARAM;
921 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
922 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
923 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
924 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
925 "sufficient privileges\n"));
926 return WERR_ACCESS_DENIED;
929 status = session_extract_session_key(p->session_info,
930 &session_key,
931 KEY_USE_16BYTES);
932 if (!NT_STATUS_IS_OK(status)) {
933 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: no session key %s\n",
934 nt_errstr(status)));
935 return WERR_NO_USER_SESSION_KEY;
938 werr = decode_wkssvc_join_password_buffer(
939 p->mem_ctx, r->in.encrypted_password,
940 &session_key, &cleartext_pwd);
941 if (!W_ERROR_IS_OK(werr)) {
942 return werr;
945 split_domain_user(p->mem_ctx,
946 r->in.account,
947 &admin_domain,
948 &admin_account);
950 werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
951 if (!W_ERROR_IS_OK(werr)) {
952 return werr;
955 u->in.domain_name = lp_realm();
956 u->in.unjoin_flags = r->in.unjoin_flags |
957 WKSSVC_JOIN_FLAGS_JOIN_TYPE;
958 u->in.admin_account = admin_account;
959 u->in.admin_password = cleartext_pwd;
960 u->in.debug = true;
961 u->in.modify_config = lp_config_backend_is_registry();
962 u->in.msg_ctx = p->msg_ctx;
964 become_root();
965 setenv(KRB5_ENV_CCNAME, "MEMORY:_wkssvc_NetrUnjoinDomain2", 1);
966 werr = libnet_Unjoin(p->mem_ctx, u);
967 unsetenv(KRB5_ENV_CCNAME);
968 unbecome_root();
970 if (!W_ERROR_IS_OK(werr)) {
971 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
972 u->out.error_string ? u->out.error_string :
973 win_errstr(werr)));
976 TALLOC_FREE(u);
977 return werr;
980 /********************************************************************
981 ********************************************************************/
983 WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
984 struct wkssvc_NetrRenameMachineInDomain2 *r)
986 /* for now just return not supported */
987 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
988 return WERR_NOT_SUPPORTED;
991 /********************************************************************
992 ********************************************************************/
994 WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
995 struct wkssvc_NetrValidateName2 *r)
997 /* FIXME: Add implementation code here */
998 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
999 return WERR_NOT_SUPPORTED;
1002 /********************************************************************
1003 ********************************************************************/
1005 WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
1006 struct wkssvc_NetrGetJoinableOus2 *r)
1008 /* FIXME: Add implementation code here */
1009 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1010 return WERR_NOT_SUPPORTED;
1013 /********************************************************************
1014 ********************************************************************/
1016 WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
1017 struct wkssvc_NetrAddAlternateComputerName *r)
1019 /* FIXME: Add implementation code here */
1020 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1021 return WERR_NOT_SUPPORTED;
1024 /********************************************************************
1025 ********************************************************************/
1027 WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
1028 struct wkssvc_NetrRemoveAlternateComputerName *r)
1030 /* FIXME: Add implementation code here */
1031 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1032 return WERR_NOT_SUPPORTED;
1035 /********************************************************************
1036 ********************************************************************/
1038 WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
1039 struct wkssvc_NetrSetPrimaryComputername *r)
1041 /* FIXME: Add implementation code here */
1042 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1043 return WERR_NOT_SUPPORTED;
1046 /********************************************************************
1047 ********************************************************************/
1049 WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
1050 struct wkssvc_NetrEnumerateComputerNames *r)
1052 /* FIXME: Add implementation code here */
1053 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
1054 return WERR_NOT_SUPPORTED;