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 "libnet/libnet.h"
27 #include "../libcli/auth/libcli_auth.h"
28 #include "../librpc/gen_ndr/srv_wkssvc.h"
31 #define DBGC_CLASS DBGC_RPC_SRV
45 struct timeval login_time
;
48 static int usr_info_cmp(const void *p1
, const void *p2
)
50 const struct usrinfo
*usr1
= (const struct usrinfo
*)p1
;
51 const struct usrinfo
*usr2
= (const struct usrinfo
*)p2
;
53 /* Called from qsort to compare two users in a usrinfo_t array for
54 * sorting by login time. Return >0 if usr1 login time was later than
55 * usr2 login time, <0 if it was earlier */
56 return timeval_compare(&usr1
->login_time
, &usr2
->login_time
);
59 /*******************************************************************
60 Get a list of the names of all users logged into this machine
61 ********************************************************************/
63 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
67 struct usrinfo
*usr_infos
= NULL
;
70 while ((u
= getutxent()) != NULL
) {
72 if (u
->ut_type
!= USER_PROCESS
) {
75 for (i
= 0; i
< num_users
; i
++) {
76 /* getutxent can return multiple user entries for the
77 * same user, so ignore any dups */
78 if (strcmp(u
->ut_user
, usr_infos
[i
].name
) == 0) {
86 tmp
= talloc_realloc(mem_ctx
, usr_infos
, struct usrinfo
,
94 usr_infos
[num_users
].name
= talloc_strdup(usr_infos
,
96 if (usr_infos
[num_users
].name
== NULL
) {
97 TALLOC_FREE(usr_infos
);
101 usr_infos
[num_users
].login_time
.tv_sec
= u
->ut_tv
.tv_sec
;
102 usr_infos
[num_users
].login_time
.tv_usec
= u
->ut_tv
.tv_usec
;
106 /* Sort the user list by time, oldest first */
107 qsort(usr_infos
, num_users
, sizeof(struct usrinfo
), usr_info_cmp
);
109 users
= (char**)talloc_array(mem_ctx
, char*, num_users
);
111 for (i
= 0; i
< num_users
; i
++) {
112 users
[i
] = talloc_move(users
, &usr_infos
[i
].name
);
115 TALLOC_FREE(usr_infos
);
123 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
130 static int dom_user_cmp(const void *p1
, const void *p2
)
132 /* Called from qsort to compare two domain users in a dom_usr_t array
133 * for sorting by login time. Return >0 if usr1 login time was later
134 * than usr2 login time, <0 if it was earlier */
135 const struct dom_usr
*usr1
= (const struct dom_usr
*)p1
;
136 const struct dom_usr
*usr2
= (const struct dom_usr
*)p2
;
138 return (usr1
->login_time
- usr2
->login_time
);
141 /*******************************************************************
142 Get a list of the names of all users of this machine who are
143 logged into the domain.
145 This should return a list of the users on this machine who are
146 logged into the domain (i.e. have been authenticated by the domain's
147 password server) but that doesn't fit well with the normal Samba
148 scenario where accesses out to the domain are made through smbclient
149 with each such session individually authenticated. So about the best
150 we can do currently is to list sessions of local users connected to
151 this server, which means that to get themself included in the list a
152 local user must create a session to the local samba server by running:
153 smbclient \\\\localhost\\share
155 FIXME: find a better way to get local users logged into the domain
157 ********************************************************************/
159 static struct dom_usr
*get_domain_userlist(TALLOC_CTX
*mem_ctx
)
161 struct sessionid
*session_list
= NULL
;
162 char *machine_name
, *p
, *nm
;
164 struct dom_usr
*users
, *tmp
;
165 int i
, num_users
, num_sessions
;
167 sep
= lp_winbind_separator();
172 num_sessions
= list_sessions(mem_ctx
, &session_list
);
173 if (num_sessions
== 0) {
178 users
= talloc_array(mem_ctx
, struct dom_usr
, num_sessions
);
180 TALLOC_FREE(session_list
);
184 for (i
=num_users
=0; i
<num_sessions
; i
++) {
185 if (!session_list
[i
].username
186 || !session_list
[i
].remote_machine
) {
189 p
= strpbrk(session_list
[i
].remote_machine
, "./");
193 machine_name
= talloc_asprintf_strupper_m(
194 users
, "%s", session_list
[i
].remote_machine
);
195 if (machine_name
== NULL
) {
196 DEBUG(10, ("talloc_asprintf failed\n"));
199 if (strcmp(machine_name
, global_myname()) == 0) {
200 p
= session_list
[i
].username
;
204 * "domain+name" format so split domain and
209 users
[num_users
].domain
=
210 talloc_asprintf_strupper_m(users
,
212 users
[num_users
].name
= talloc_strdup(users
,
216 * Simple user name so get domain from smb.conf
218 users
[num_users
].domain
=
219 talloc_strdup(users
, lp_workgroup());
220 users
[num_users
].name
= talloc_strdup(users
,
223 users
[num_users
].login_time
=
224 session_list
[i
].connect_start
;
227 TALLOC_FREE(machine_name
);
229 TALLOC_FREE(session_list
);
231 tmp
= talloc_realloc(mem_ctx
, users
, struct dom_usr
, num_users
);
237 /* Sort the user list by time, oldest first */
238 qsort(users
, num_users
, sizeof(struct dom_usr
), dom_user_cmp
);
244 /*******************************************************************
245 RPC Workstation Service request NetWkstaGetInfo with level 100.
246 Returns to the requester:
248 - The smb version number
250 Returns a filled in wkssvc_NetWkstaInfo100 struct.
251 ********************************************************************/
253 static struct wkssvc_NetWkstaInfo100
*create_wks_info_100(TALLOC_CTX
*mem_ctx
)
255 struct wkssvc_NetWkstaInfo100
*info100
;
257 info100
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo100
);
258 if (info100
== NULL
) {
262 info100
->platform_id
= PLATFORM_ID_NT
; /* unknown */
263 info100
->version_major
= lp_major_announce_version();
264 info100
->version_minor
= lp_minor_announce_version();
266 info100
->server_name
= talloc_asprintf_strupper_m(
267 info100
, "%s", global_myname());
268 info100
->domain_name
= talloc_asprintf_strupper_m(
269 info100
, "%s", lp_workgroup());
274 /*******************************************************************
275 RPC Workstation Service request NetWkstaGetInfo with level 101.
276 Returns to the requester:
277 - As per NetWkstaGetInfo with level 100, plus:
278 - The LANMAN directory path (not currently supported).
279 Returns a filled in wkssvc_NetWkstaInfo101 struct.
280 ********************************************************************/
282 static struct wkssvc_NetWkstaInfo101
*create_wks_info_101(TALLOC_CTX
*mem_ctx
)
284 struct wkssvc_NetWkstaInfo101
*info101
;
286 info101
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo101
);
287 if (info101
== NULL
) {
291 info101
->platform_id
= PLATFORM_ID_NT
; /* unknown */
292 info101
->version_major
= lp_major_announce_version();
293 info101
->version_minor
= lp_minor_announce_version();
295 info101
->server_name
= talloc_asprintf_strupper_m(
296 info101
, "%s", global_myname());
297 info101
->domain_name
= talloc_asprintf_strupper_m(
298 info101
, "%s", lp_workgroup());
299 info101
->lan_root
= "";
304 /*******************************************************************
305 RPC Workstation Service request NetWkstaGetInfo with level 102.
306 Returns to the requester:
307 - As per NetWkstaGetInfo with level 101, plus:
308 - The number of logged in users.
309 Returns a filled in wkssvc_NetWkstaInfo102 struct.
310 ********************************************************************/
312 static struct wkssvc_NetWkstaInfo102
*create_wks_info_102(TALLOC_CTX
*mem_ctx
)
314 struct wkssvc_NetWkstaInfo102
*info102
;
317 info102
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo102
);
318 if (info102
== NULL
) {
322 info102
->platform_id
= PLATFORM_ID_NT
; /* unknown */
323 info102
->version_major
= lp_major_announce_version();
324 info102
->version_minor
= lp_minor_announce_version();
326 info102
->server_name
= talloc_asprintf_strupper_m(
327 info102
, "%s", global_myname());
328 info102
->domain_name
= talloc_asprintf_strupper_m(
329 info102
, "%s", lp_workgroup());
330 info102
->lan_root
= "";
332 users
= get_logged_on_userlist(talloc_tos());
333 info102
->logged_on_users
= talloc_array_length(users
);
340 /********************************************************************
341 Handling for RPC Workstation Service request NetWkstaGetInfo
342 ********************************************************************/
344 WERROR
_wkssvc_NetWkstaGetInfo(pipes_struct
*p
, 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
->server_info
->ptok
)) {
359 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
361 DEBUGADD(3,(" - does not have sid for Authenticated "
364 &global_sid_Authenticated_Users
)));
365 debug_nt_user_token(DBGC_CLASS
, 3,
366 p
->server_info
->ptok
);
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
->server_info
->ptok
)) {
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 debug_nt_user_token(DBGC_CLASS
, 3,
384 p
->server_info
->ptok
);
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(pipes_struct
*p
, 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(pipes_struct
*p
, struct wkssvc_NetWkstaEnumUsers
*r
)
559 /* This with any level should only be allowed from a domain administrator */
560 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
561 p
->server_info
->ptok
)) {
562 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
563 DEBUGADD(3,(" - does not have sid for Administrators group "
564 "%s\n", sid_string_dbg(
565 &global_sid_Builtin_Administrators
)));
566 debug_nt_user_token(DBGC_CLASS
, 3, p
->server_info
->ptok
);
567 return WERR_ACCESS_DENIED
;
570 switch (r
->in
.info
->level
) {
572 r
->out
.info
->ctr
.user0
= create_enum_users0(p
->mem_ctx
);
573 if (r
->out
.info
->ctr
.user0
== NULL
) {
576 r
->out
.info
->level
= r
->in
.info
->level
;
577 *r
->out
.entries_read
= r
->out
.info
->ctr
.user0
->entries_read
;
578 *r
->out
.resume_handle
= 0;
581 r
->out
.info
->ctr
.user1
= create_enum_users1(p
->mem_ctx
);
582 if (r
->out
.info
->ctr
.user1
== NULL
) {
585 r
->out
.info
->level
= r
->in
.info
->level
;
586 *r
->out
.entries_read
= r
->out
.info
->ctr
.user1
->entries_read
;
587 *r
->out
.resume_handle
= 0;
590 return WERR_UNKNOWN_LEVEL
;
596 /********************************************************************
597 ********************************************************************/
599 WERROR
_wkssvc_NetrWkstaUserGetInfo(pipes_struct
*p
, struct wkssvc_NetrWkstaUserGetInfo
*r
)
601 /* FIXME: Add implementation code here */
602 p
->rng_fault_state
= True
;
603 return WERR_NOT_SUPPORTED
;
606 /********************************************************************
607 ********************************************************************/
609 WERROR
_wkssvc_NetrWkstaUserSetInfo(pipes_struct
*p
, struct wkssvc_NetrWkstaUserSetInfo
*r
)
611 /* FIXME: Add implementation code here */
612 p
->rng_fault_state
= True
;
613 return WERR_NOT_SUPPORTED
;
616 /********************************************************************
617 ********************************************************************/
619 WERROR
_wkssvc_NetWkstaTransportEnum(pipes_struct
*p
, struct wkssvc_NetWkstaTransportEnum
*r
)
621 /* FIXME: Add implementation code here */
622 p
->rng_fault_state
= True
;
623 return WERR_NOT_SUPPORTED
;
626 /********************************************************************
627 ********************************************************************/
629 WERROR
_wkssvc_NetrWkstaTransportAdd(pipes_struct
*p
, struct wkssvc_NetrWkstaTransportAdd
*r
)
631 /* FIXME: Add implementation code here */
632 p
->rng_fault_state
= True
;
633 return WERR_NOT_SUPPORTED
;
636 /********************************************************************
637 ********************************************************************/
639 WERROR
_wkssvc_NetrWkstaTransportDel(pipes_struct
*p
, struct wkssvc_NetrWkstaTransportDel
*r
)
641 /* FIXME: Add implementation code here */
642 p
->rng_fault_state
= True
;
643 return WERR_NOT_SUPPORTED
;
646 /********************************************************************
647 ********************************************************************/
649 WERROR
_wkssvc_NetrUseAdd(pipes_struct
*p
, struct wkssvc_NetrUseAdd
*r
)
651 /* FIXME: Add implementation code here */
652 p
->rng_fault_state
= True
;
653 return WERR_NOT_SUPPORTED
;
656 /********************************************************************
657 ********************************************************************/
659 WERROR
_wkssvc_NetrUseGetInfo(pipes_struct
*p
, struct wkssvc_NetrUseGetInfo
*r
)
661 /* FIXME: Add implementation code here */
662 p
->rng_fault_state
= True
;
663 return WERR_NOT_SUPPORTED
;
666 /********************************************************************
667 ********************************************************************/
669 WERROR
_wkssvc_NetrUseDel(pipes_struct
*p
, struct wkssvc_NetrUseDel
*r
)
671 /* FIXME: Add implementation code here */
672 p
->rng_fault_state
= True
;
673 return WERR_NOT_SUPPORTED
;
676 /********************************************************************
677 ********************************************************************/
679 WERROR
_wkssvc_NetrUseEnum(pipes_struct
*p
, struct wkssvc_NetrUseEnum
*r
)
681 /* FIXME: Add implementation code here */
682 p
->rng_fault_state
= True
;
683 return WERR_NOT_SUPPORTED
;
686 /********************************************************************
687 ********************************************************************/
689 WERROR
_wkssvc_NetrMessageBufferSend(pipes_struct
*p
, struct wkssvc_NetrMessageBufferSend
*r
)
691 /* FIXME: Add implementation code here */
692 p
->rng_fault_state
= True
;
693 return WERR_NOT_SUPPORTED
;
696 /********************************************************************
697 ********************************************************************/
699 WERROR
_wkssvc_NetrWorkstationStatisticsGet(pipes_struct
*p
, struct wkssvc_NetrWorkstationStatisticsGet
*r
)
701 /* FIXME: Add implementation code here */
702 p
->rng_fault_state
= True
;
703 return WERR_NOT_SUPPORTED
;
706 /********************************************************************
707 ********************************************************************/
709 WERROR
_wkssvc_NetrLogonDomainNameAdd(pipes_struct
*p
, struct wkssvc_NetrLogonDomainNameAdd
*r
)
711 /* FIXME: Add implementation code here */
712 p
->rng_fault_state
= True
;
713 return WERR_NOT_SUPPORTED
;
716 /********************************************************************
717 ********************************************************************/
719 WERROR
_wkssvc_NetrLogonDomainNameDel(pipes_struct
*p
, struct wkssvc_NetrLogonDomainNameDel
*r
)
721 /* FIXME: Add implementation code here */
722 p
->rng_fault_state
= True
;
723 return WERR_NOT_SUPPORTED
;
726 /********************************************************************
727 ********************************************************************/
729 WERROR
_wkssvc_NetrJoinDomain(pipes_struct
*p
, struct wkssvc_NetrJoinDomain
*r
)
731 /* FIXME: Add implementation code here */
732 p
->rng_fault_state
= True
;
733 return WERR_NOT_SUPPORTED
;
736 /********************************************************************
737 ********************************************************************/
739 WERROR
_wkssvc_NetrUnjoinDomain(pipes_struct
*p
, struct wkssvc_NetrUnjoinDomain
*r
)
741 /* FIXME: Add implementation code here */
742 p
->rng_fault_state
= True
;
743 return WERR_NOT_SUPPORTED
;
746 /********************************************************************
747 ********************************************************************/
749 WERROR
_wkssvc_NetrRenameMachineInDomain(pipes_struct
*p
, struct wkssvc_NetrRenameMachineInDomain
*r
)
751 /* FIXME: Add implementation code here */
752 p
->rng_fault_state
= True
;
753 return WERR_NOT_SUPPORTED
;
756 /********************************************************************
757 ********************************************************************/
759 WERROR
_wkssvc_NetrValidateName(pipes_struct
*p
, struct wkssvc_NetrValidateName
*r
)
761 /* FIXME: Add implementation code here */
762 p
->rng_fault_state
= True
;
763 return WERR_NOT_SUPPORTED
;
766 /********************************************************************
767 ********************************************************************/
769 WERROR
_wkssvc_NetrGetJoinInformation(pipes_struct
*p
, struct wkssvc_NetrGetJoinInformation
*r
)
771 /* FIXME: Add implementation code here */
772 p
->rng_fault_state
= True
;
773 return WERR_NOT_SUPPORTED
;
776 /********************************************************************
777 ********************************************************************/
779 WERROR
_wkssvc_NetrGetJoinableOus(pipes_struct
*p
, struct wkssvc_NetrGetJoinableOus
*r
)
781 /* FIXME: Add implementation code here */
782 p
->rng_fault_state
= True
;
783 return WERR_NOT_SUPPORTED
;
786 /********************************************************************
787 _wkssvc_NetrJoinDomain2
788 ********************************************************************/
790 WERROR
_wkssvc_NetrJoinDomain2(pipes_struct
*p
,
791 struct wkssvc_NetrJoinDomain2
*r
)
793 struct libnet_JoinCtx
*j
= NULL
;
794 char *cleartext_pwd
= NULL
;
795 char *admin_domain
= NULL
;
796 char *admin_account
= NULL
;
798 struct nt_user_token
*token
= p
->server_info
->ptok
;
800 if (!r
->in
.domain_name
) {
801 return WERR_INVALID_PARAM
;
804 if (!r
->in
.admin_account
|| !r
->in
.encrypted_password
) {
805 return WERR_INVALID_PARAM
;
808 if (!user_has_privileges(token
, &se_machine_account
) &&
809 !nt_token_check_domain_rid(token
, DOMAIN_GROUP_RID_ADMINS
) &&
810 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
811 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
812 "sufficient privileges\n"));
813 return WERR_ACCESS_DENIED
;
816 if ((r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
) ||
817 (r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
)) {
818 return WERR_NOT_SUPPORTED
;
821 werr
= decode_wkssvc_join_password_buffer(
822 p
->mem_ctx
, r
->in
.encrypted_password
,
823 &p
->server_info
->user_session_key
, &cleartext_pwd
);
824 if (!W_ERROR_IS_OK(werr
)) {
828 split_domain_user(p
->mem_ctx
,
833 werr
= libnet_init_JoinCtx(p
->mem_ctx
, &j
);
834 if (!W_ERROR_IS_OK(werr
)) {
838 j
->in
.domain_name
= r
->in
.domain_name
;
839 j
->in
.account_ou
= r
->in
.account_ou
;
840 j
->in
.join_flags
= r
->in
.join_flags
;
841 j
->in
.admin_account
= admin_account
;
842 j
->in
.admin_password
= cleartext_pwd
;
844 j
->in
.modify_config
= lp_config_backend_is_registry();
845 j
->in
.msg_ctx
= smbd_messaging_context();
848 werr
= libnet_Join(p
->mem_ctx
, j
);
851 if (!W_ERROR_IS_OK(werr
)) {
852 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
853 j
->out
.error_string
? j
->out
.error_string
:
861 /********************************************************************
862 _wkssvc_NetrUnjoinDomain2
863 ********************************************************************/
865 WERROR
_wkssvc_NetrUnjoinDomain2(pipes_struct
*p
,
866 struct wkssvc_NetrUnjoinDomain2
*r
)
868 struct libnet_UnjoinCtx
*u
= NULL
;
869 char *cleartext_pwd
= NULL
;
870 char *admin_domain
= NULL
;
871 char *admin_account
= NULL
;
873 struct nt_user_token
*token
= p
->server_info
->ptok
;
875 if (!r
->in
.account
|| !r
->in
.encrypted_password
) {
876 return WERR_INVALID_PARAM
;
879 if (!user_has_privileges(token
, &se_machine_account
) &&
880 !nt_token_check_domain_rid(token
, DOMAIN_GROUP_RID_ADMINS
) &&
881 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
882 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
883 "sufficient privileges\n"));
884 return WERR_ACCESS_DENIED
;
887 werr
= decode_wkssvc_join_password_buffer(
888 p
->mem_ctx
, r
->in
.encrypted_password
,
889 &p
->server_info
->user_session_key
, &cleartext_pwd
);
890 if (!W_ERROR_IS_OK(werr
)) {
894 split_domain_user(p
->mem_ctx
,
899 werr
= libnet_init_UnjoinCtx(p
->mem_ctx
, &u
);
900 if (!W_ERROR_IS_OK(werr
)) {
904 u
->in
.domain_name
= lp_realm();
905 u
->in
.unjoin_flags
= r
->in
.unjoin_flags
|
906 WKSSVC_JOIN_FLAGS_JOIN_TYPE
;
907 u
->in
.admin_account
= admin_account
;
908 u
->in
.admin_password
= cleartext_pwd
;
910 u
->in
.modify_config
= lp_config_backend_is_registry();
911 u
->in
.msg_ctx
= smbd_messaging_context();
914 werr
= libnet_Unjoin(p
->mem_ctx
, u
);
917 if (!W_ERROR_IS_OK(werr
)) {
918 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
919 u
->out
.error_string
? u
->out
.error_string
:
927 /********************************************************************
928 ********************************************************************/
930 WERROR
_wkssvc_NetrRenameMachineInDomain2(pipes_struct
*p
, struct wkssvc_NetrRenameMachineInDomain2
*r
)
932 /* for now just return not supported */
933 return WERR_NOT_SUPPORTED
;
936 /********************************************************************
937 ********************************************************************/
939 WERROR
_wkssvc_NetrValidateName2(pipes_struct
*p
, struct wkssvc_NetrValidateName2
*r
)
941 /* FIXME: Add implementation code here */
942 p
->rng_fault_state
= True
;
943 return WERR_NOT_SUPPORTED
;
946 /********************************************************************
947 ********************************************************************/
949 WERROR
_wkssvc_NetrGetJoinableOus2(pipes_struct
*p
, struct wkssvc_NetrGetJoinableOus2
*r
)
951 /* FIXME: Add implementation code here */
952 p
->rng_fault_state
= True
;
953 return WERR_NOT_SUPPORTED
;
956 /********************************************************************
957 ********************************************************************/
959 WERROR
_wkssvc_NetrAddAlternateComputerName(pipes_struct
*p
, struct wkssvc_NetrAddAlternateComputerName
*r
)
961 /* FIXME: Add implementation code here */
962 p
->rng_fault_state
= True
;
963 return WERR_NOT_SUPPORTED
;
966 /********************************************************************
967 ********************************************************************/
969 WERROR
_wkssvc_NetrRemoveAlternateComputerName(pipes_struct
*p
, struct wkssvc_NetrRemoveAlternateComputerName
*r
)
971 /* FIXME: Add implementation code here */
972 p
->rng_fault_state
= True
;
973 return WERR_NOT_SUPPORTED
;
976 /********************************************************************
977 ********************************************************************/
979 WERROR
_wkssvc_NetrSetPrimaryComputername(pipes_struct
*p
, struct wkssvc_NetrSetPrimaryComputername
*r
)
981 /* FIXME: Add implementation code here */
982 p
->rng_fault_state
= True
;
983 return WERR_NOT_SUPPORTED
;
986 /********************************************************************
987 ********************************************************************/
989 WERROR
_wkssvc_NetrEnumerateComputerNames(pipes_struct
*p
, struct wkssvc_NetrEnumerateComputerNames
*r
)
991 /* FIXME: Add implementation code here */
992 p
->rng_fault_state
= True
;
993 return WERR_NOT_SUPPORTED
;