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. */
26 #include "librpc/gen_ndr/libnet_join.h"
27 #include "libnet/libnet_join.h"
28 #include "../libcli/auth/libcli_auth.h"
29 #include "../librpc/gen_ndr/srv_wkssvc.h"
30 #include "../libcli/security/security.h"
32 #include "smbd/smbd.h"
35 #define DBGC_CLASS DBGC_RPC_SRV
49 struct timeval login_time;
52 static int usr_info_cmp(const struct usrinfo *usr1, const struct usrinfo *usr2)
54 /* Called from qsort to compare two users in a usrinfo_t array for
55 * sorting by login time. Return >0 if usr1 login time was later than
56 * usr2 login time, <0 if it was earlier */
57 return timeval_compare(&usr1->login_time, &usr2->login_time);
60 /*******************************************************************
61 Get a list of the names of all users logged into this machine
62 ********************************************************************/
64 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
68 struct usrinfo *usr_infos = NULL;
71 while ((u = getutxent()) != NULL) {
73 if (u->ut_type != USER_PROCESS) {
76 for (i = 0; i < num_users; i++) {
77 /* getutxent can return multiple user entries for the
78 * same user, so ignore any dups */
79 if (strcmp(u->ut_user, usr_infos[i].name) == 0) {
87 tmp = talloc_realloc(mem_ctx, usr_infos, struct usrinfo,
95 usr_infos[num_users].name = talloc_strdup(usr_infos,
97 if (usr_infos[num_users].name == NULL) {
98 TALLOC_FREE(usr_infos);
102 usr_infos[num_users].login_time.tv_sec = u->ut_tv.tv_sec;
103 usr_infos[num_users].login_time.tv_usec = u->ut_tv.tv_usec;
107 /* Sort the user list by time, oldest first */
108 TYPESAFE_QSORT(usr_infos, num_users, usr_info_cmp);
110 users = (char**)talloc_array(mem_ctx, char*, num_users);
112 for (i = 0; i < num_users; i++) {
113 users[i] = talloc_move(users, &usr_infos[i].name);
116 TALLOC_FREE(usr_infos);
124 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
131 static int dom_user_cmp(const struct dom_usr *usr1, const struct dom_usr *usr2)
133 /* Called from qsort to compare two domain users in a dom_usr_t array
134 * for sorting by login time. Return >0 if usr1 login time was later
135 * than usr2 login time, <0 if it was earlier */
136 return (usr1->login_time - usr2->login_time);
139 /*******************************************************************
140 Get a list of the names of all users of this machine who are
141 logged into the domain.
143 This should return a list of the users on this machine who are
144 logged into the domain (i.e. have been authenticated by the domain's
145 password server) but that doesn't fit well with the normal Samba
146 scenario where accesses out to the domain are made through smbclient
147 with each such session individually authenticated. So about the best
148 we can do currently is to list sessions of local users connected to
149 this server, which means that to get themself included in the list a
150 local user must create a session to the local samba server by running:
151 smbclient \\\\localhost\\share
153 FIXME: find a better way to get local users logged into the domain
155 ********************************************************************/
157 static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx)
159 struct sessionid *session_list = NULL;
160 char *machine_name, *p, *nm;
162 struct dom_usr *users, *tmp;
163 int i, num_users, num_sessions;
165 sep = lp_winbind_separator();
170 num_sessions = list_sessions(mem_ctx, &session_list);
171 if (num_sessions == 0) {
176 users = talloc_array(mem_ctx, struct dom_usr, num_sessions);
178 TALLOC_FREE(session_list);
182 for (i=num_users=0; i<num_sessions; i++) {
183 if (!session_list[i].username
184 || !session_list[i].remote_machine) {
187 p = strpbrk(session_list[i].remote_machine, "./");
191 machine_name = talloc_asprintf_strupper_m(
192 users, "%s", session_list[i].remote_machine);
193 if (machine_name == NULL) {
194 DEBUG(10, ("talloc_asprintf failed\n"));
197 if (strcmp(machine_name, global_myname()) == 0) {
198 p = session_list[i].username;
202 * "domain+name" format so split domain and
207 users[num_users].domain =
208 talloc_asprintf_strupper_m(users,
210 users[num_users].name = talloc_strdup(users,
214 * Simple user name so get domain from smb.conf
216 users[num_users].domain =
217 talloc_strdup(users, lp_workgroup());
218 users[num_users].name = talloc_strdup(users,
221 users[num_users].login_time =
222 session_list[i].connect_start;
225 TALLOC_FREE(machine_name);
227 TALLOC_FREE(session_list);
229 tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users);
235 /* Sort the user list by time, oldest first */
236 TYPESAFE_QSORT(users, num_users, dom_user_cmp);
242 /*******************************************************************
243 RPC Workstation Service request NetWkstaGetInfo with level 100.
244 Returns to the requester:
246 - The smb version number
248 Returns a filled in wkssvc_NetWkstaInfo100 struct.
249 ********************************************************************/
251 static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx)
253 struct wkssvc_NetWkstaInfo100 *info100;
255 info100 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo100);
256 if (info100 == NULL) {
260 info100->platform_id = PLATFORM_ID_NT; /* unknown */
261 info100->version_major = lp_major_announce_version();
262 info100->version_minor = lp_minor_announce_version();
264 info100->server_name = talloc_asprintf_strupper_m(
265 info100, "%s", global_myname());
266 info100->domain_name = talloc_asprintf_strupper_m(
267 info100, "%s", lp_workgroup());
272 /*******************************************************************
273 RPC Workstation Service request NetWkstaGetInfo with level 101.
274 Returns to the requester:
275 - As per NetWkstaGetInfo with level 100, plus:
276 - The LANMAN directory path (not currently supported).
277 Returns a filled in wkssvc_NetWkstaInfo101 struct.
278 ********************************************************************/
280 static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx)
282 struct wkssvc_NetWkstaInfo101 *info101;
284 info101 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo101);
285 if (info101 == NULL) {
289 info101->platform_id = PLATFORM_ID_NT; /* unknown */
290 info101->version_major = lp_major_announce_version();
291 info101->version_minor = lp_minor_announce_version();
293 info101->server_name = talloc_asprintf_strupper_m(
294 info101, "%s", global_myname());
295 info101->domain_name = talloc_asprintf_strupper_m(
296 info101, "%s", lp_workgroup());
297 info101->lan_root = "";
302 /*******************************************************************
303 RPC Workstation Service request NetWkstaGetInfo with level 102.
304 Returns to the requester:
305 - As per NetWkstaGetInfo with level 101, plus:
306 - The number of logged in users.
307 Returns a filled in wkssvc_NetWkstaInfo102 struct.
308 ********************************************************************/
310 static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
312 struct wkssvc_NetWkstaInfo102 *info102;
315 info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
316 if (info102 == NULL) {
320 info102->platform_id = PLATFORM_ID_NT; /* unknown */
321 info102->version_major = lp_major_announce_version();
322 info102->version_minor = lp_minor_announce_version();
324 info102->server_name = talloc_asprintf_strupper_m(
325 info102, "%s", global_myname());
326 info102->domain_name = talloc_asprintf_strupper_m(
327 info102, "%s", lp_workgroup());
328 info102->lan_root = "";
330 users = get_logged_on_userlist(talloc_tos());
331 info102->logged_on_users = talloc_array_length(users);
338 /********************************************************************
339 Handling for RPC Workstation Service request NetWkstaGetInfo
340 ********************************************************************/
342 WERROR _wkssvc_NetWkstaGetInfo(struct pipes_struct *p,
343 struct wkssvc_NetWkstaGetInfo *r)
345 switch (r->in.level) {
347 /* Level 100 can be allowed from anyone including anonymous
348 * so no access checks are needed for this case */
349 r->out.info->info100 = create_wks_info_100(p->mem_ctx);
350 if (r->out.info->info100 == NULL) {
355 /* Level 101 can be allowed from any logged in user */
356 if (!nt_token_check_sid(&global_sid_Authenticated_Users,
357 p->session_info->security_token)) {
358 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
360 DEBUGADD(3,(" - does not have sid for Authenticated "
363 &global_sid_Authenticated_Users)));
364 security_token_debug(DBGC_CLASS, 3,
365 p->session_info->security_token);
366 return WERR_ACCESS_DENIED;
368 r->out.info->info101 = create_wks_info_101(p->mem_ctx);
369 if (r->out.info->info101 == NULL) {
374 /* Level 102 Should only be allowed from a domain administrator */
375 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
376 p->session_info->security_token)) {
377 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
379 DEBUGADD(3,(" - does not have sid for Administrators "
380 "group %s, sids are:\n",
381 sid_string_dbg(&global_sid_Builtin_Administrators)));
382 security_token_debug(DBGC_CLASS, 3,
383 p->session_info->security_token);
384 return WERR_ACCESS_DENIED;
386 r->out.info->info102 = create_wks_info_102(p->mem_ctx);
387 if (r->out.info->info102 == NULL) {
392 return WERR_UNKNOWN_LEVEL;
398 /********************************************************************
399 ********************************************************************/
401 WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
402 struct wkssvc_NetWkstaSetInfo *r)
404 /* FIXME: Add implementation code here */
405 p->rng_fault_state = True;
406 return WERR_NOT_SUPPORTED;
409 /********************************************************************
410 RPC Workstation Service request NetWkstaEnumUsers with level 0:
411 Returns to the requester:
412 - the user names of the logged in users.
413 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
414 ********************************************************************/
416 static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0(
419 struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0;
423 ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0);
428 users = get_logged_on_userlist(talloc_tos());
429 if (users == NULL && errno != 0) {
430 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
431 errno, strerror(errno)));
436 num_users = talloc_array_length(users);
437 ctr0->entries_read = num_users;
438 ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0,
440 if (ctr0->user0 == NULL) {
446 for (i=0; i<num_users; i++) {
447 ctr0->user0[i].user_name = talloc_move(ctr0->user0, &users[i]);
453 /********************************************************************
454 RPC Workstation Service request NetWkstaEnumUsers with level 1.
455 Returns to the requester:
456 - the user names of the logged in users,
457 - the domain or machine each is logged into,
458 - the password server that was used to authenticate each,
459 - other domains each user is logged into (not currently supported).
460 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
461 ********************************************************************/
463 static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1(
466 struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1;
468 struct dom_usr *dom_users;
469 const char *pwd_server;
471 int i, j, num_users, num_dom_users;
473 ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1);
478 users = get_logged_on_userlist(talloc_tos());
479 if (users == NULL && errno != 0) {
480 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
481 errno, strerror(errno)));
485 num_users = talloc_array_length(users);
487 dom_users = get_domain_userlist(talloc_tos());
488 if (dom_users == NULL && errno != 0) {
493 num_dom_users = talloc_array_length(dom_users);
495 ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1,
496 num_users+num_dom_users);
497 if (ctr1->user1 == NULL) {
500 TALLOC_FREE(dom_users);
506 if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_passwordserver()))) {
507 /* The configured password server is a full DNS name but
508 * for the logon server we need to return just the first
509 * component (machine name) of it in upper-case */
510 char *p = strchr(pwd_tmp, '.');
514 p = pwd_tmp + strlen(pwd_tmp);
516 while (--p >= pwd_tmp) {
519 pwd_server = pwd_tmp;
522 /* Put in local users first */
523 for (i=0; i<num_users; i++) {
524 ctr1->user1[i].user_name = talloc_move(ctr1->user1, &users[i]);
526 /* For a local user the domain name and logon server are
527 * both returned as the local machine's NetBIOS name */
528 ctr1->user1[i].logon_domain = ctr1->user1[i].logon_server =
529 talloc_asprintf_strupper_m(ctr1->user1, "%s", global_myname());
531 ctr1->user1[i].other_domains = NULL; /* Maybe in future? */
534 /* Now domain users */
535 for (j=0; j<num_dom_users; j++) {
536 ctr1->user1[i].user_name =
537 talloc_strdup(ctr1->user1, dom_users[j].name);
538 ctr1->user1[i].logon_domain =
539 talloc_strdup(ctr1->user1, dom_users[j].domain);
540 ctr1->user1[i].logon_server = pwd_server;
542 ctr1->user1[i++].other_domains = NULL; /* Maybe in future? */
545 ctr1->entries_read = i;
548 TALLOC_FREE(dom_users);
552 /********************************************************************
553 Handling for RPC Workstation Service request NetWkstaEnumUsers
554 (a.k.a Windows NetWkstaUserEnum)
555 ********************************************************************/
557 WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
558 struct wkssvc_NetWkstaEnumUsers *r)
560 /* This with any level should only be allowed from a domain administrator */
561 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
562 p->session_info->security_token)) {
563 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
564 DEBUGADD(3,(" - does not have sid for Administrators group "
565 "%s\n", sid_string_dbg(
566 &global_sid_Builtin_Administrators)));
567 security_token_debug(DBGC_CLASS, 3, p->session_info->security_token);
568 return WERR_ACCESS_DENIED;
571 switch (r->in.info->level) {
573 r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
574 if (r->out.info->ctr.user0 == NULL) {
577 r->out.info->level = r->in.info->level;
578 *r->out.entries_read = r->out.info->ctr.user0->entries_read;
579 *r->out.resume_handle = 0;
582 r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
583 if (r->out.info->ctr.user1 == NULL) {
586 r->out.info->level = r->in.info->level;
587 *r->out.entries_read = r->out.info->ctr.user1->entries_read;
588 *r->out.resume_handle = 0;
591 return WERR_UNKNOWN_LEVEL;
597 /********************************************************************
598 ********************************************************************/
600 WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
601 struct wkssvc_NetrWkstaUserGetInfo *r)
603 /* FIXME: Add implementation code here */
604 p->rng_fault_state = True;
605 return WERR_NOT_SUPPORTED;
608 /********************************************************************
609 ********************************************************************/
611 WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
612 struct wkssvc_NetrWkstaUserSetInfo *r)
614 /* FIXME: Add implementation code here */
615 p->rng_fault_state = True;
616 return WERR_NOT_SUPPORTED;
619 /********************************************************************
620 ********************************************************************/
622 WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
623 struct wkssvc_NetWkstaTransportEnum *r)
625 /* FIXME: Add implementation code here */
626 p->rng_fault_state = True;
627 return WERR_NOT_SUPPORTED;
630 /********************************************************************
631 ********************************************************************/
633 WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
634 struct wkssvc_NetrWkstaTransportAdd *r)
636 /* FIXME: Add implementation code here */
637 p->rng_fault_state = True;
638 return WERR_NOT_SUPPORTED;
641 /********************************************************************
642 ********************************************************************/
644 WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
645 struct wkssvc_NetrWkstaTransportDel *r)
647 /* FIXME: Add implementation code here */
648 p->rng_fault_state = True;
649 return WERR_NOT_SUPPORTED;
652 /********************************************************************
653 ********************************************************************/
655 WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
656 struct wkssvc_NetrUseAdd *r)
658 /* FIXME: Add implementation code here */
659 p->rng_fault_state = True;
660 return WERR_NOT_SUPPORTED;
663 /********************************************************************
664 ********************************************************************/
666 WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
667 struct wkssvc_NetrUseGetInfo *r)
669 /* FIXME: Add implementation code here */
670 p->rng_fault_state = True;
671 return WERR_NOT_SUPPORTED;
674 /********************************************************************
675 ********************************************************************/
677 WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
678 struct wkssvc_NetrUseDel *r)
680 /* FIXME: Add implementation code here */
681 p->rng_fault_state = True;
682 return WERR_NOT_SUPPORTED;
685 /********************************************************************
686 ********************************************************************/
688 WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
689 struct wkssvc_NetrUseEnum *r)
691 /* FIXME: Add implementation code here */
692 p->rng_fault_state = True;
693 return WERR_NOT_SUPPORTED;
696 /********************************************************************
697 ********************************************************************/
699 WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
700 struct wkssvc_NetrMessageBufferSend *r)
702 /* FIXME: Add implementation code here */
703 p->rng_fault_state = True;
704 return WERR_NOT_SUPPORTED;
707 /********************************************************************
708 ********************************************************************/
710 WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
711 struct wkssvc_NetrWorkstationStatisticsGet *r)
713 /* FIXME: Add implementation code here */
714 p->rng_fault_state = True;
715 return WERR_NOT_SUPPORTED;
718 /********************************************************************
719 ********************************************************************/
721 WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
722 struct wkssvc_NetrLogonDomainNameAdd *r)
724 /* FIXME: Add implementation code here */
725 p->rng_fault_state = True;
726 return WERR_NOT_SUPPORTED;
729 /********************************************************************
730 ********************************************************************/
732 WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
733 struct wkssvc_NetrLogonDomainNameDel *r)
735 /* FIXME: Add implementation code here */
736 p->rng_fault_state = True;
737 return WERR_NOT_SUPPORTED;
740 /********************************************************************
741 ********************************************************************/
743 WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
744 struct wkssvc_NetrJoinDomain *r)
746 /* FIXME: Add implementation code here */
747 p->rng_fault_state = True;
748 return WERR_NOT_SUPPORTED;
751 /********************************************************************
752 ********************************************************************/
754 WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
755 struct wkssvc_NetrUnjoinDomain *r)
757 /* FIXME: Add implementation code here */
758 p->rng_fault_state = True;
759 return WERR_NOT_SUPPORTED;
762 /********************************************************************
763 ********************************************************************/
765 WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
766 struct wkssvc_NetrRenameMachineInDomain *r)
768 /* FIXME: Add implementation code here */
769 p->rng_fault_state = True;
770 return WERR_NOT_SUPPORTED;
773 /********************************************************************
774 ********************************************************************/
776 WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
777 struct wkssvc_NetrValidateName *r)
779 /* FIXME: Add implementation code here */
780 p->rng_fault_state = True;
781 return WERR_NOT_SUPPORTED;
784 /********************************************************************
785 ********************************************************************/
787 WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
788 struct wkssvc_NetrGetJoinInformation *r)
790 /* FIXME: Add implementation code here */
791 p->rng_fault_state = True;
792 return WERR_NOT_SUPPORTED;
795 /********************************************************************
796 ********************************************************************/
798 WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
799 struct wkssvc_NetrGetJoinableOus *r)
801 /* FIXME: Add implementation code here */
802 p->rng_fault_state = True;
803 return WERR_NOT_SUPPORTED;
806 /********************************************************************
807 _wkssvc_NetrJoinDomain2
808 ********************************************************************/
810 WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
811 struct wkssvc_NetrJoinDomain2 *r)
813 struct libnet_JoinCtx *j = NULL;
814 char *cleartext_pwd = NULL;
815 char *admin_domain = NULL;
816 char *admin_account = NULL;
818 struct security_token *token = p->session_info->security_token;
820 if (!r->in.domain_name) {
821 return WERR_INVALID_PARAM;
824 if (!r->in.admin_account || !r->in.encrypted_password) {
825 return WERR_INVALID_PARAM;
828 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
829 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
830 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
831 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
832 "sufficient privileges\n"));
833 return WERR_ACCESS_DENIED;
836 if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) ||
837 (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
838 return WERR_NOT_SUPPORTED;
841 werr = decode_wkssvc_join_password_buffer(
842 p->mem_ctx, r->in.encrypted_password,
843 &p->session_info->user_session_key, &cleartext_pwd);
844 if (!W_ERROR_IS_OK(werr)) {
848 split_domain_user(p->mem_ctx,
853 werr = libnet_init_JoinCtx(p->mem_ctx, &j);
854 if (!W_ERROR_IS_OK(werr)) {
858 j->in.domain_name = r->in.domain_name;
859 j->in.account_ou = r->in.account_ou;
860 j->in.join_flags = r->in.join_flags;
861 j->in.admin_account = admin_account;
862 j->in.admin_password = cleartext_pwd;
864 j->in.modify_config = lp_config_backend_is_registry();
865 j->in.msg_ctx = p->msg_ctx;
868 werr = libnet_Join(p->mem_ctx, j);
871 if (!W_ERROR_IS_OK(werr)) {
872 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
873 j->out.error_string ? j->out.error_string :
881 /********************************************************************
882 _wkssvc_NetrUnjoinDomain2
883 ********************************************************************/
885 WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
886 struct wkssvc_NetrUnjoinDomain2 *r)
888 struct libnet_UnjoinCtx *u = NULL;
889 char *cleartext_pwd = NULL;
890 char *admin_domain = NULL;
891 char *admin_account = NULL;
893 struct security_token *token = p->session_info->security_token;
895 if (!r->in.account || !r->in.encrypted_password) {
896 return WERR_INVALID_PARAM;
899 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
900 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
901 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
902 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
903 "sufficient privileges\n"));
904 return WERR_ACCESS_DENIED;
907 werr = decode_wkssvc_join_password_buffer(
908 p->mem_ctx, r->in.encrypted_password,
909 &p->session_info->user_session_key, &cleartext_pwd);
910 if (!W_ERROR_IS_OK(werr)) {
914 split_domain_user(p->mem_ctx,
919 werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
920 if (!W_ERROR_IS_OK(werr)) {
924 u->in.domain_name = lp_realm();
925 u->in.unjoin_flags = r->in.unjoin_flags |
926 WKSSVC_JOIN_FLAGS_JOIN_TYPE;
927 u->in.admin_account = admin_account;
928 u->in.admin_password = cleartext_pwd;
930 u->in.modify_config = lp_config_backend_is_registry();
931 u->in.msg_ctx = p->msg_ctx;
934 werr = libnet_Unjoin(p->mem_ctx, u);
937 if (!W_ERROR_IS_OK(werr)) {
938 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
939 u->out.error_string ? u->out.error_string :
947 /********************************************************************
948 ********************************************************************/
950 WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
951 struct wkssvc_NetrRenameMachineInDomain2 *r)
953 /* for now just return not supported */
954 return WERR_NOT_SUPPORTED;
957 /********************************************************************
958 ********************************************************************/
960 WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
961 struct wkssvc_NetrValidateName2 *r)
963 /* FIXME: Add implementation code here */
964 p->rng_fault_state = True;
965 return WERR_NOT_SUPPORTED;
968 /********************************************************************
969 ********************************************************************/
971 WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
972 struct wkssvc_NetrGetJoinableOus2 *r)
974 /* FIXME: Add implementation code here */
975 p->rng_fault_state = True;
976 return WERR_NOT_SUPPORTED;
979 /********************************************************************
980 ********************************************************************/
982 WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
983 struct wkssvc_NetrAddAlternateComputerName *r)
985 /* FIXME: Add implementation code here */
986 p->rng_fault_state = True;
987 return WERR_NOT_SUPPORTED;
990 /********************************************************************
991 ********************************************************************/
993 WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
994 struct wkssvc_NetrRemoveAlternateComputerName *r)
996 /* FIXME: Add implementation code here */
997 p->rng_fault_state = True;
998 return WERR_NOT_SUPPORTED;
1001 /********************************************************************
1002 ********************************************************************/
1004 WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
1005 struct wkssvc_NetrSetPrimaryComputername *r)
1007 /* FIXME: Add implementation code here */
1008 p->rng_fault_state = True;
1009 return WERR_NOT_SUPPORTED;
1012 /********************************************************************
1013 ********************************************************************/
1015 WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
1016 struct wkssvc_NetrEnumerateComputerNames *r)
1018 /* FIXME: Add implementation code here */
1019 p->rng_fault_state = True;
1020 return WERR_NOT_SUPPORTED;