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"
36 #define DBGC_CLASS DBGC_RPC_SRV
50 struct timeval login_time;
53 static int usr_info_cmp(const struct usrinfo *usr1, const struct usrinfo *usr2)
55 /* Called from qsort to compare two users in a usrinfo_t array for
56 * sorting by login time. Return >0 if usr1 login time was later than
57 * usr2 login time, <0 if it was earlier */
58 return timeval_compare(&usr1->login_time, &usr2->login_time);
61 /*******************************************************************
62 Get a list of the names of all users logged into this machine
63 ********************************************************************/
65 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
69 struct usrinfo *usr_infos = NULL;
72 while ((u = getutxent()) != NULL) {
74 if (u->ut_type != USER_PROCESS) {
77 for (i = 0; i < num_users; i++) {
78 /* getutxent can return multiple user entries for the
79 * same user, so ignore any dups */
80 if (strcmp(u->ut_user, usr_infos[i].name) == 0) {
88 tmp = talloc_realloc(mem_ctx, usr_infos, struct usrinfo,
96 usr_infos[num_users].name = talloc_strdup(usr_infos,
98 if (usr_infos[num_users].name == NULL) {
99 TALLOC_FREE(usr_infos);
103 usr_infos[num_users].login_time.tv_sec = u->ut_tv.tv_sec;
104 usr_infos[num_users].login_time.tv_usec = u->ut_tv.tv_usec;
108 /* Sort the user list by time, oldest first */
109 TYPESAFE_QSORT(usr_infos, num_users, usr_info_cmp);
111 users = (char**)talloc_array(mem_ctx, char*, num_users);
113 for (i = 0; i < num_users; i++) {
114 users[i] = talloc_move(users, &usr_infos[i].name);
117 TALLOC_FREE(usr_infos);
125 static char **get_logged_on_userlist(TALLOC_CTX *mem_ctx)
132 static int dom_user_cmp(const struct dom_usr *usr1, const struct dom_usr *usr2)
134 /* Called from qsort to compare two domain users in a dom_usr_t array
135 * for sorting by login time. Return >0 if usr1 login time was later
136 * than usr2 login time, <0 if it was earlier */
137 return (usr1->login_time - usr2->login_time);
140 /*******************************************************************
141 Get a list of the names of all users of this machine who are
142 logged into the domain.
144 This should return a list of the users on this machine who are
145 logged into the domain (i.e. have been authenticated by the domain's
146 password server) but that doesn't fit well with the normal Samba
147 scenario where accesses out to the domain are made through smbclient
148 with each such session individually authenticated. So about the best
149 we can do currently is to list sessions of local users connected to
150 this server, which means that to get themself included in the list a
151 local user must create a session to the local samba server by running:
152 smbclient \\\\localhost\\share
154 FIXME: find a better way to get local users logged into the domain
156 ********************************************************************/
158 static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx)
160 struct sessionid *session_list = NULL;
161 char *machine_name, *p, *nm;
163 struct dom_usr *users, *tmp;
164 int i, num_users, num_sessions;
166 sep = lp_winbind_separator();
171 num_sessions = list_sessions(mem_ctx, &session_list);
172 if (num_sessions == 0) {
177 users = talloc_array(mem_ctx, struct dom_usr, num_sessions);
179 TALLOC_FREE(session_list);
183 for (i=num_users=0; i<num_sessions; i++) {
184 if (!session_list[i].username
185 || !session_list[i].remote_machine) {
188 p = strpbrk(session_list[i].remote_machine, "./");
192 machine_name = talloc_asprintf_strupper_m(
193 users, "%s", session_list[i].remote_machine);
194 if (machine_name == NULL) {
195 DEBUG(10, ("talloc_asprintf failed\n"));
198 if (strcmp(machine_name, global_myname()) == 0) {
199 p = session_list[i].username;
203 * "domain+name" format so split domain and
208 users[num_users].domain =
209 talloc_asprintf_strupper_m(users,
211 users[num_users].name = talloc_strdup(users,
215 * Simple user name so get domain from smb.conf
217 users[num_users].domain =
218 talloc_strdup(users, lp_workgroup());
219 users[num_users].name = talloc_strdup(users,
222 users[num_users].login_time =
223 session_list[i].connect_start;
226 TALLOC_FREE(machine_name);
228 TALLOC_FREE(session_list);
230 tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users);
236 /* Sort the user list by time, oldest first */
237 TYPESAFE_QSORT(users, num_users, dom_user_cmp);
243 /*******************************************************************
244 RPC Workstation Service request NetWkstaGetInfo with level 100.
245 Returns to the requester:
247 - The smb version number
249 Returns a filled in wkssvc_NetWkstaInfo100 struct.
250 ********************************************************************/
252 static struct wkssvc_NetWkstaInfo100 *create_wks_info_100(TALLOC_CTX *mem_ctx)
254 struct wkssvc_NetWkstaInfo100 *info100;
256 info100 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo100);
257 if (info100 == NULL) {
261 info100->platform_id = PLATFORM_ID_NT; /* unknown */
262 info100->version_major = lp_major_announce_version();
263 info100->version_minor = lp_minor_announce_version();
265 info100->server_name = talloc_asprintf_strupper_m(
266 info100, "%s", global_myname());
267 info100->domain_name = talloc_asprintf_strupper_m(
268 info100, "%s", lp_workgroup());
273 /*******************************************************************
274 RPC Workstation Service request NetWkstaGetInfo with level 101.
275 Returns to the requester:
276 - As per NetWkstaGetInfo with level 100, plus:
277 - The LANMAN directory path (not currently supported).
278 Returns a filled in wkssvc_NetWkstaInfo101 struct.
279 ********************************************************************/
281 static struct wkssvc_NetWkstaInfo101 *create_wks_info_101(TALLOC_CTX *mem_ctx)
283 struct wkssvc_NetWkstaInfo101 *info101;
285 info101 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo101);
286 if (info101 == NULL) {
290 info101->platform_id = PLATFORM_ID_NT; /* unknown */
291 info101->version_major = lp_major_announce_version();
292 info101->version_minor = lp_minor_announce_version();
294 info101->server_name = talloc_asprintf_strupper_m(
295 info101, "%s", global_myname());
296 info101->domain_name = talloc_asprintf_strupper_m(
297 info101, "%s", lp_workgroup());
298 info101->lan_root = "";
303 /*******************************************************************
304 RPC Workstation Service request NetWkstaGetInfo with level 102.
305 Returns to the requester:
306 - As per NetWkstaGetInfo with level 101, plus:
307 - The number of logged in users.
308 Returns a filled in wkssvc_NetWkstaInfo102 struct.
309 ********************************************************************/
311 static struct wkssvc_NetWkstaInfo102 *create_wks_info_102(TALLOC_CTX *mem_ctx)
313 struct wkssvc_NetWkstaInfo102 *info102;
316 info102 = talloc(mem_ctx, struct wkssvc_NetWkstaInfo102);
317 if (info102 == NULL) {
321 info102->platform_id = PLATFORM_ID_NT; /* unknown */
322 info102->version_major = lp_major_announce_version();
323 info102->version_minor = lp_minor_announce_version();
325 info102->server_name = talloc_asprintf_strupper_m(
326 info102, "%s", global_myname());
327 info102->domain_name = talloc_asprintf_strupper_m(
328 info102, "%s", lp_workgroup());
329 info102->lan_root = "";
331 users = get_logged_on_userlist(talloc_tos());
332 info102->logged_on_users = talloc_array_length(users);
339 /********************************************************************
340 Handling for RPC Workstation Service request NetWkstaGetInfo
341 ********************************************************************/
343 WERROR _wkssvc_NetWkstaGetInfo(struct pipes_struct *p,
344 struct wkssvc_NetWkstaGetInfo *r)
346 switch (r->in.level) {
348 /* Level 100 can be allowed from anyone including anonymous
349 * so no access checks are needed for this case */
350 r->out.info->info100 = create_wks_info_100(p->mem_ctx);
351 if (r->out.info->info100 == NULL) {
356 /* Level 101 can be allowed from any logged in user */
357 if (!nt_token_check_sid(&global_sid_Authenticated_Users,
358 p->session_info->security_token)) {
359 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
361 DEBUGADD(3,(" - does not have sid for Authenticated "
364 &global_sid_Authenticated_Users)));
365 security_token_debug(DBGC_CLASS, 3,
366 p->session_info->security_token);
367 return WERR_ACCESS_DENIED;
369 r->out.info->info101 = create_wks_info_101(p->mem_ctx);
370 if (r->out.info->info101 == NULL) {
375 /* Level 102 Should only be allowed from a domain administrator */
376 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
377 p->session_info->security_token)) {
378 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
380 DEBUGADD(3,(" - does not have sid for Administrators "
381 "group %s, sids are:\n",
382 sid_string_dbg(&global_sid_Builtin_Administrators)));
383 security_token_debug(DBGC_CLASS, 3,
384 p->session_info->security_token);
385 return WERR_ACCESS_DENIED;
387 r->out.info->info102 = create_wks_info_102(p->mem_ctx);
388 if (r->out.info->info102 == NULL) {
393 return WERR_UNKNOWN_LEVEL;
399 /********************************************************************
400 ********************************************************************/
402 WERROR _wkssvc_NetWkstaSetInfo(struct pipes_struct *p,
403 struct wkssvc_NetWkstaSetInfo *r)
405 /* FIXME: Add implementation code here */
406 p->rng_fault_state = True;
407 return WERR_NOT_SUPPORTED;
410 /********************************************************************
411 RPC Workstation Service request NetWkstaEnumUsers with level 0:
412 Returns to the requester:
413 - the user names of the logged in users.
414 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
415 ********************************************************************/
417 static struct wkssvc_NetWkstaEnumUsersCtr0 *create_enum_users0(
420 struct wkssvc_NetWkstaEnumUsersCtr0 *ctr0;
424 ctr0 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr0);
429 users = get_logged_on_userlist(talloc_tos());
430 if (users == NULL && errno != 0) {
431 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
432 errno, strerror(errno)));
437 num_users = talloc_array_length(users);
438 ctr0->entries_read = num_users;
439 ctr0->user0 = talloc_array(ctr0, struct wkssvc_NetrWkstaUserInfo0,
441 if (ctr0->user0 == NULL) {
447 for (i=0; i<num_users; i++) {
448 ctr0->user0[i].user_name = talloc_move(ctr0->user0, &users[i]);
454 /********************************************************************
455 RPC Workstation Service request NetWkstaEnumUsers with level 1.
456 Returns to the requester:
457 - the user names of the logged in users,
458 - the domain or machine each is logged into,
459 - the password server that was used to authenticate each,
460 - other domains each user is logged into (not currently supported).
461 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
462 ********************************************************************/
464 static struct wkssvc_NetWkstaEnumUsersCtr1 *create_enum_users1(
467 struct wkssvc_NetWkstaEnumUsersCtr1 *ctr1;
469 struct dom_usr *dom_users;
470 const char *pwd_server;
472 int i, j, num_users, num_dom_users;
474 ctr1 = talloc(mem_ctx, struct wkssvc_NetWkstaEnumUsersCtr1);
479 users = get_logged_on_userlist(talloc_tos());
480 if (users == NULL && errno != 0) {
481 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
482 errno, strerror(errno)));
486 num_users = talloc_array_length(users);
488 dom_users = get_domain_userlist(talloc_tos());
489 if (dom_users == NULL && errno != 0) {
494 num_dom_users = talloc_array_length(dom_users);
496 ctr1->user1 = talloc_array(ctr1, struct wkssvc_NetrWkstaUserInfo1,
497 num_users+num_dom_users);
498 if (ctr1->user1 == NULL) {
501 TALLOC_FREE(dom_users);
507 if ((pwd_tmp = talloc_strdup(ctr1->user1, lp_passwordserver()))) {
508 /* The configured password server is a full DNS name but
509 * for the logon server we need to return just the first
510 * component (machine name) of it in upper-case */
511 char *p = strchr(pwd_tmp, '.');
515 p = pwd_tmp + strlen(pwd_tmp);
517 while (--p >= pwd_tmp) {
520 pwd_server = pwd_tmp;
523 /* Put in local users first */
524 for (i=0; i<num_users; i++) {
525 ctr1->user1[i].user_name = talloc_move(ctr1->user1, &users[i]);
527 /* For a local user the domain name and logon server are
528 * both returned as the local machine's NetBIOS name */
529 ctr1->user1[i].logon_domain = ctr1->user1[i].logon_server =
530 talloc_asprintf_strupper_m(ctr1->user1, "%s", global_myname());
532 ctr1->user1[i].other_domains = NULL; /* Maybe in future? */
535 /* Now domain users */
536 for (j=0; j<num_dom_users; j++) {
537 ctr1->user1[i].user_name =
538 talloc_strdup(ctr1->user1, dom_users[j].name);
539 ctr1->user1[i].logon_domain =
540 talloc_strdup(ctr1->user1, dom_users[j].domain);
541 ctr1->user1[i].logon_server = pwd_server;
543 ctr1->user1[i++].other_domains = NULL; /* Maybe in future? */
546 ctr1->entries_read = i;
549 TALLOC_FREE(dom_users);
553 /********************************************************************
554 Handling for RPC Workstation Service request NetWkstaEnumUsers
555 (a.k.a Windows NetWkstaUserEnum)
556 ********************************************************************/
558 WERROR _wkssvc_NetWkstaEnumUsers(struct pipes_struct *p,
559 struct wkssvc_NetWkstaEnumUsers *r)
561 /* This with any level should only be allowed from a domain administrator */
562 if (!nt_token_check_sid(&global_sid_Builtin_Administrators,
563 p->session_info->security_token)) {
564 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
565 DEBUGADD(3,(" - does not have sid for Administrators group "
566 "%s\n", sid_string_dbg(
567 &global_sid_Builtin_Administrators)));
568 security_token_debug(DBGC_CLASS, 3, p->session_info->security_token);
569 return WERR_ACCESS_DENIED;
572 switch (r->in.info->level) {
574 r->out.info->ctr.user0 = create_enum_users0(p->mem_ctx);
575 if (r->out.info->ctr.user0 == NULL) {
578 r->out.info->level = r->in.info->level;
579 *r->out.entries_read = r->out.info->ctr.user0->entries_read;
580 *r->out.resume_handle = 0;
583 r->out.info->ctr.user1 = create_enum_users1(p->mem_ctx);
584 if (r->out.info->ctr.user1 == NULL) {
587 r->out.info->level = r->in.info->level;
588 *r->out.entries_read = r->out.info->ctr.user1->entries_read;
589 *r->out.resume_handle = 0;
592 return WERR_UNKNOWN_LEVEL;
598 /********************************************************************
599 ********************************************************************/
601 WERROR _wkssvc_NetrWkstaUserGetInfo(struct pipes_struct *p,
602 struct wkssvc_NetrWkstaUserGetInfo *r)
604 /* FIXME: Add implementation code here */
605 p->rng_fault_state = True;
606 return WERR_NOT_SUPPORTED;
609 /********************************************************************
610 ********************************************************************/
612 WERROR _wkssvc_NetrWkstaUserSetInfo(struct pipes_struct *p,
613 struct wkssvc_NetrWkstaUserSetInfo *r)
615 /* FIXME: Add implementation code here */
616 p->rng_fault_state = True;
617 return WERR_NOT_SUPPORTED;
620 /********************************************************************
621 ********************************************************************/
623 WERROR _wkssvc_NetWkstaTransportEnum(struct pipes_struct *p,
624 struct wkssvc_NetWkstaTransportEnum *r)
626 /* FIXME: Add implementation code here */
627 p->rng_fault_state = True;
628 return WERR_NOT_SUPPORTED;
631 /********************************************************************
632 ********************************************************************/
634 WERROR _wkssvc_NetrWkstaTransportAdd(struct pipes_struct *p,
635 struct wkssvc_NetrWkstaTransportAdd *r)
637 /* FIXME: Add implementation code here */
638 p->rng_fault_state = True;
639 return WERR_NOT_SUPPORTED;
642 /********************************************************************
643 ********************************************************************/
645 WERROR _wkssvc_NetrWkstaTransportDel(struct pipes_struct *p,
646 struct wkssvc_NetrWkstaTransportDel *r)
648 /* FIXME: Add implementation code here */
649 p->rng_fault_state = True;
650 return WERR_NOT_SUPPORTED;
653 /********************************************************************
654 ********************************************************************/
656 WERROR _wkssvc_NetrUseAdd(struct pipes_struct *p,
657 struct wkssvc_NetrUseAdd *r)
659 /* FIXME: Add implementation code here */
660 p->rng_fault_state = True;
661 return WERR_NOT_SUPPORTED;
664 /********************************************************************
665 ********************************************************************/
667 WERROR _wkssvc_NetrUseGetInfo(struct pipes_struct *p,
668 struct wkssvc_NetrUseGetInfo *r)
670 /* FIXME: Add implementation code here */
671 p->rng_fault_state = True;
672 return WERR_NOT_SUPPORTED;
675 /********************************************************************
676 ********************************************************************/
678 WERROR _wkssvc_NetrUseDel(struct pipes_struct *p,
679 struct wkssvc_NetrUseDel *r)
681 /* FIXME: Add implementation code here */
682 p->rng_fault_state = True;
683 return WERR_NOT_SUPPORTED;
686 /********************************************************************
687 ********************************************************************/
689 WERROR _wkssvc_NetrUseEnum(struct pipes_struct *p,
690 struct wkssvc_NetrUseEnum *r)
692 /* FIXME: Add implementation code here */
693 p->rng_fault_state = True;
694 return WERR_NOT_SUPPORTED;
697 /********************************************************************
698 ********************************************************************/
700 WERROR _wkssvc_NetrMessageBufferSend(struct pipes_struct *p,
701 struct wkssvc_NetrMessageBufferSend *r)
703 /* FIXME: Add implementation code here */
704 p->rng_fault_state = True;
705 return WERR_NOT_SUPPORTED;
708 /********************************************************************
709 ********************************************************************/
711 WERROR _wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct *p,
712 struct wkssvc_NetrWorkstationStatisticsGet *r)
714 /* FIXME: Add implementation code here */
715 p->rng_fault_state = True;
716 return WERR_NOT_SUPPORTED;
719 /********************************************************************
720 ********************************************************************/
722 WERROR _wkssvc_NetrLogonDomainNameAdd(struct pipes_struct *p,
723 struct wkssvc_NetrLogonDomainNameAdd *r)
725 /* FIXME: Add implementation code here */
726 p->rng_fault_state = True;
727 return WERR_NOT_SUPPORTED;
730 /********************************************************************
731 ********************************************************************/
733 WERROR _wkssvc_NetrLogonDomainNameDel(struct pipes_struct *p,
734 struct wkssvc_NetrLogonDomainNameDel *r)
736 /* FIXME: Add implementation code here */
737 p->rng_fault_state = True;
738 return WERR_NOT_SUPPORTED;
741 /********************************************************************
742 ********************************************************************/
744 WERROR _wkssvc_NetrJoinDomain(struct pipes_struct *p,
745 struct wkssvc_NetrJoinDomain *r)
747 /* FIXME: Add implementation code here */
748 p->rng_fault_state = True;
749 return WERR_NOT_SUPPORTED;
752 /********************************************************************
753 ********************************************************************/
755 WERROR _wkssvc_NetrUnjoinDomain(struct pipes_struct *p,
756 struct wkssvc_NetrUnjoinDomain *r)
758 /* FIXME: Add implementation code here */
759 p->rng_fault_state = True;
760 return WERR_NOT_SUPPORTED;
763 /********************************************************************
764 ********************************************************************/
766 WERROR _wkssvc_NetrRenameMachineInDomain(struct pipes_struct *p,
767 struct wkssvc_NetrRenameMachineInDomain *r)
769 /* FIXME: Add implementation code here */
770 p->rng_fault_state = True;
771 return WERR_NOT_SUPPORTED;
774 /********************************************************************
775 ********************************************************************/
777 WERROR _wkssvc_NetrValidateName(struct pipes_struct *p,
778 struct wkssvc_NetrValidateName *r)
780 /* FIXME: Add implementation code here */
781 p->rng_fault_state = True;
782 return WERR_NOT_SUPPORTED;
785 /********************************************************************
786 ********************************************************************/
788 WERROR _wkssvc_NetrGetJoinInformation(struct pipes_struct *p,
789 struct wkssvc_NetrGetJoinInformation *r)
791 /* FIXME: Add implementation code here */
792 p->rng_fault_state = True;
793 return WERR_NOT_SUPPORTED;
796 /********************************************************************
797 ********************************************************************/
799 WERROR _wkssvc_NetrGetJoinableOus(struct pipes_struct *p,
800 struct wkssvc_NetrGetJoinableOus *r)
802 /* FIXME: Add implementation code here */
803 p->rng_fault_state = True;
804 return WERR_NOT_SUPPORTED;
807 /********************************************************************
808 _wkssvc_NetrJoinDomain2
809 ********************************************************************/
811 WERROR _wkssvc_NetrJoinDomain2(struct pipes_struct *p,
812 struct wkssvc_NetrJoinDomain2 *r)
814 struct libnet_JoinCtx *j = NULL;
815 char *cleartext_pwd = NULL;
816 char *admin_domain = NULL;
817 char *admin_account = NULL;
819 struct security_token *token = p->session_info->security_token;
821 if (!r->in.domain_name) {
822 return WERR_INVALID_PARAM;
825 if (!r->in.admin_account || !r->in.encrypted_password) {
826 return WERR_INVALID_PARAM;
829 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
830 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
831 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
832 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
833 "sufficient privileges\n"));
834 return WERR_ACCESS_DENIED;
837 if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED) ||
838 (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
839 return WERR_NOT_SUPPORTED;
842 werr = decode_wkssvc_join_password_buffer(
843 p->mem_ctx, r->in.encrypted_password,
844 &p->session_info->user_session_key, &cleartext_pwd);
845 if (!W_ERROR_IS_OK(werr)) {
849 split_domain_user(p->mem_ctx,
854 werr = libnet_init_JoinCtx(p->mem_ctx, &j);
855 if (!W_ERROR_IS_OK(werr)) {
859 j->in.domain_name = r->in.domain_name;
860 j->in.account_ou = r->in.account_ou;
861 j->in.join_flags = r->in.join_flags;
862 j->in.admin_account = admin_account;
863 j->in.admin_password = cleartext_pwd;
865 j->in.modify_config = lp_config_backend_is_registry();
866 j->in.msg_ctx = p->msg_ctx;
869 werr = libnet_Join(p->mem_ctx, j);
872 if (!W_ERROR_IS_OK(werr)) {
873 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
874 j->out.error_string ? j->out.error_string :
882 /********************************************************************
883 _wkssvc_NetrUnjoinDomain2
884 ********************************************************************/
886 WERROR _wkssvc_NetrUnjoinDomain2(struct pipes_struct *p,
887 struct wkssvc_NetrUnjoinDomain2 *r)
889 struct libnet_UnjoinCtx *u = NULL;
890 char *cleartext_pwd = NULL;
891 char *admin_domain = NULL;
892 char *admin_account = NULL;
894 struct security_token *token = p->session_info->security_token;
896 if (!r->in.account || !r->in.encrypted_password) {
897 return WERR_INVALID_PARAM;
900 if (!security_token_has_privilege(token, SEC_PRIV_MACHINE_ACCOUNT) &&
901 !nt_token_check_domain_rid(token, DOMAIN_RID_ADMINS) &&
902 !nt_token_check_sid(&global_sid_Builtin_Administrators, token)) {
903 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
904 "sufficient privileges\n"));
905 return WERR_ACCESS_DENIED;
908 werr = decode_wkssvc_join_password_buffer(
909 p->mem_ctx, r->in.encrypted_password,
910 &p->session_info->user_session_key, &cleartext_pwd);
911 if (!W_ERROR_IS_OK(werr)) {
915 split_domain_user(p->mem_ctx,
920 werr = libnet_init_UnjoinCtx(p->mem_ctx, &u);
921 if (!W_ERROR_IS_OK(werr)) {
925 u->in.domain_name = lp_realm();
926 u->in.unjoin_flags = r->in.unjoin_flags |
927 WKSSVC_JOIN_FLAGS_JOIN_TYPE;
928 u->in.admin_account = admin_account;
929 u->in.admin_password = cleartext_pwd;
931 u->in.modify_config = lp_config_backend_is_registry();
932 u->in.msg_ctx = p->msg_ctx;
935 werr = libnet_Unjoin(p->mem_ctx, u);
938 if (!W_ERROR_IS_OK(werr)) {
939 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
940 u->out.error_string ? u->out.error_string :
948 /********************************************************************
949 ********************************************************************/
951 WERROR _wkssvc_NetrRenameMachineInDomain2(struct pipes_struct *p,
952 struct wkssvc_NetrRenameMachineInDomain2 *r)
954 /* for now just return not supported */
955 return WERR_NOT_SUPPORTED;
958 /********************************************************************
959 ********************************************************************/
961 WERROR _wkssvc_NetrValidateName2(struct pipes_struct *p,
962 struct wkssvc_NetrValidateName2 *r)
964 /* FIXME: Add implementation code here */
965 p->rng_fault_state = True;
966 return WERR_NOT_SUPPORTED;
969 /********************************************************************
970 ********************************************************************/
972 WERROR _wkssvc_NetrGetJoinableOus2(struct pipes_struct *p,
973 struct wkssvc_NetrGetJoinableOus2 *r)
975 /* FIXME: Add implementation code here */
976 p->rng_fault_state = True;
977 return WERR_NOT_SUPPORTED;
980 /********************************************************************
981 ********************************************************************/
983 WERROR _wkssvc_NetrAddAlternateComputerName(struct pipes_struct *p,
984 struct wkssvc_NetrAddAlternateComputerName *r)
986 /* FIXME: Add implementation code here */
987 p->rng_fault_state = True;
988 return WERR_NOT_SUPPORTED;
991 /********************************************************************
992 ********************************************************************/
994 WERROR _wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct *p,
995 struct wkssvc_NetrRemoveAlternateComputerName *r)
997 /* FIXME: Add implementation code here */
998 p->rng_fault_state = True;
999 return WERR_NOT_SUPPORTED;
1002 /********************************************************************
1003 ********************************************************************/
1005 WERROR _wkssvc_NetrSetPrimaryComputername(struct pipes_struct *p,
1006 struct wkssvc_NetrSetPrimaryComputername *r)
1008 /* FIXME: Add implementation code here */
1009 p->rng_fault_state = True;
1010 return WERR_NOT_SUPPORTED;
1013 /********************************************************************
1014 ********************************************************************/
1016 WERROR _wkssvc_NetrEnumerateComputerNames(struct pipes_struct *p,
1017 struct wkssvc_NetrEnumerateComputerNames *r)
1019 /* FIXME: Add implementation code here */
1020 p->rng_fault_state = True;
1021 return WERR_NOT_SUPPORTED;