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"
32 #define DBGC_CLASS DBGC_RPC_SRV
46 struct timeval login_time
;
49 static int usr_info_cmp(const struct usrinfo
*usr1
, const struct usrinfo
*usr2
)
51 /* Called from qsort to compare two users in a usrinfo_t array for
52 * sorting by login time. Return >0 if usr1 login time was later than
53 * usr2 login time, <0 if it was earlier */
54 return timeval_compare(&usr1
->login_time
, &usr2
->login_time
);
57 /*******************************************************************
58 Get a list of the names of all users logged into this machine
59 ********************************************************************/
61 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
65 struct usrinfo
*usr_infos
= NULL
;
68 while ((u
= getutxent()) != NULL
) {
70 if (u
->ut_type
!= USER_PROCESS
) {
73 for (i
= 0; i
< num_users
; i
++) {
74 /* getutxent can return multiple user entries for the
75 * same user, so ignore any dups */
76 if (strcmp(u
->ut_user
, usr_infos
[i
].name
) == 0) {
84 tmp
= talloc_realloc(mem_ctx
, usr_infos
, struct usrinfo
,
92 usr_infos
[num_users
].name
= talloc_strdup(usr_infos
,
94 if (usr_infos
[num_users
].name
== NULL
) {
95 TALLOC_FREE(usr_infos
);
99 usr_infos
[num_users
].login_time
.tv_sec
= u
->ut_tv
.tv_sec
;
100 usr_infos
[num_users
].login_time
.tv_usec
= u
->ut_tv
.tv_usec
;
104 /* Sort the user list by time, oldest first */
105 TYPESAFE_QSORT(usr_infos
, num_users
, usr_info_cmp
);
107 users
= (char**)talloc_array(mem_ctx
, char*, num_users
);
109 for (i
= 0; i
< num_users
; i
++) {
110 users
[i
] = talloc_move(users
, &usr_infos
[i
].name
);
113 TALLOC_FREE(usr_infos
);
121 static char **get_logged_on_userlist(TALLOC_CTX
*mem_ctx
)
128 static int dom_user_cmp(const struct dom_usr
*usr1
, const struct dom_usr
*usr2
)
130 /* Called from qsort to compare two domain users in a dom_usr_t array
131 * for sorting by login time. Return >0 if usr1 login time was later
132 * than usr2 login time, <0 if it was earlier */
133 return (usr1
->login_time
- usr2
->login_time
);
136 /*******************************************************************
137 Get a list of the names of all users of this machine who are
138 logged into the domain.
140 This should return a list of the users on this machine who are
141 logged into the domain (i.e. have been authenticated by the domain's
142 password server) but that doesn't fit well with the normal Samba
143 scenario where accesses out to the domain are made through smbclient
144 with each such session individually authenticated. So about the best
145 we can do currently is to list sessions of local users connected to
146 this server, which means that to get themself included in the list a
147 local user must create a session to the local samba server by running:
148 smbclient \\\\localhost\\share
150 FIXME: find a better way to get local users logged into the domain
152 ********************************************************************/
154 static struct dom_usr
*get_domain_userlist(TALLOC_CTX
*mem_ctx
)
156 struct sessionid
*session_list
= NULL
;
157 char *machine_name
, *p
, *nm
;
159 struct dom_usr
*users
, *tmp
;
160 int i
, num_users
, num_sessions
;
162 sep
= lp_winbind_separator();
167 num_sessions
= list_sessions(mem_ctx
, &session_list
);
168 if (num_sessions
== 0) {
173 users
= talloc_array(mem_ctx
, struct dom_usr
, num_sessions
);
175 TALLOC_FREE(session_list
);
179 for (i
=num_users
=0; i
<num_sessions
; i
++) {
180 if (!session_list
[i
].username
181 || !session_list
[i
].remote_machine
) {
184 p
= strpbrk(session_list
[i
].remote_machine
, "./");
188 machine_name
= talloc_asprintf_strupper_m(
189 users
, "%s", session_list
[i
].remote_machine
);
190 if (machine_name
== NULL
) {
191 DEBUG(10, ("talloc_asprintf failed\n"));
194 if (strcmp(machine_name
, global_myname()) == 0) {
195 p
= session_list
[i
].username
;
199 * "domain+name" format so split domain and
204 users
[num_users
].domain
=
205 talloc_asprintf_strupper_m(users
,
207 users
[num_users
].name
= talloc_strdup(users
,
211 * Simple user name so get domain from smb.conf
213 users
[num_users
].domain
=
214 talloc_strdup(users
, lp_workgroup());
215 users
[num_users
].name
= talloc_strdup(users
,
218 users
[num_users
].login_time
=
219 session_list
[i
].connect_start
;
222 TALLOC_FREE(machine_name
);
224 TALLOC_FREE(session_list
);
226 tmp
= talloc_realloc(mem_ctx
, users
, struct dom_usr
, num_users
);
232 /* Sort the user list by time, oldest first */
233 TYPESAFE_QSORT(users
, num_users
, dom_user_cmp
);
239 /*******************************************************************
240 RPC Workstation Service request NetWkstaGetInfo with level 100.
241 Returns to the requester:
243 - The smb version number
245 Returns a filled in wkssvc_NetWkstaInfo100 struct.
246 ********************************************************************/
248 static struct wkssvc_NetWkstaInfo100
*create_wks_info_100(TALLOC_CTX
*mem_ctx
)
250 struct wkssvc_NetWkstaInfo100
*info100
;
252 info100
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo100
);
253 if (info100
== NULL
) {
257 info100
->platform_id
= PLATFORM_ID_NT
; /* unknown */
258 info100
->version_major
= lp_major_announce_version();
259 info100
->version_minor
= lp_minor_announce_version();
261 info100
->server_name
= talloc_asprintf_strupper_m(
262 info100
, "%s", global_myname());
263 info100
->domain_name
= talloc_asprintf_strupper_m(
264 info100
, "%s", lp_workgroup());
269 /*******************************************************************
270 RPC Workstation Service request NetWkstaGetInfo with level 101.
271 Returns to the requester:
272 - As per NetWkstaGetInfo with level 100, plus:
273 - The LANMAN directory path (not currently supported).
274 Returns a filled in wkssvc_NetWkstaInfo101 struct.
275 ********************************************************************/
277 static struct wkssvc_NetWkstaInfo101
*create_wks_info_101(TALLOC_CTX
*mem_ctx
)
279 struct wkssvc_NetWkstaInfo101
*info101
;
281 info101
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo101
);
282 if (info101
== NULL
) {
286 info101
->platform_id
= PLATFORM_ID_NT
; /* unknown */
287 info101
->version_major
= lp_major_announce_version();
288 info101
->version_minor
= lp_minor_announce_version();
290 info101
->server_name
= talloc_asprintf_strupper_m(
291 info101
, "%s", global_myname());
292 info101
->domain_name
= talloc_asprintf_strupper_m(
293 info101
, "%s", lp_workgroup());
294 info101
->lan_root
= "";
299 /*******************************************************************
300 RPC Workstation Service request NetWkstaGetInfo with level 102.
301 Returns to the requester:
302 - As per NetWkstaGetInfo with level 101, plus:
303 - The number of logged in users.
304 Returns a filled in wkssvc_NetWkstaInfo102 struct.
305 ********************************************************************/
307 static struct wkssvc_NetWkstaInfo102
*create_wks_info_102(TALLOC_CTX
*mem_ctx
)
309 struct wkssvc_NetWkstaInfo102
*info102
;
312 info102
= talloc(mem_ctx
, struct wkssvc_NetWkstaInfo102
);
313 if (info102
== NULL
) {
317 info102
->platform_id
= PLATFORM_ID_NT
; /* unknown */
318 info102
->version_major
= lp_major_announce_version();
319 info102
->version_minor
= lp_minor_announce_version();
321 info102
->server_name
= talloc_asprintf_strupper_m(
322 info102
, "%s", global_myname());
323 info102
->domain_name
= talloc_asprintf_strupper_m(
324 info102
, "%s", lp_workgroup());
325 info102
->lan_root
= "";
327 users
= get_logged_on_userlist(talloc_tos());
328 info102
->logged_on_users
= talloc_array_length(users
);
335 /********************************************************************
336 Handling for RPC Workstation Service request NetWkstaGetInfo
337 ********************************************************************/
339 WERROR
_wkssvc_NetWkstaGetInfo(struct pipes_struct
*p
,
340 struct wkssvc_NetWkstaGetInfo
*r
)
342 switch (r
->in
.level
) {
344 /* Level 100 can be allowed from anyone including anonymous
345 * so no access checks are needed for this case */
346 r
->out
.info
->info100
= create_wks_info_100(p
->mem_ctx
);
347 if (r
->out
.info
->info100
== NULL
) {
352 /* Level 101 can be allowed from any logged in user */
353 if (!nt_token_check_sid(&global_sid_Authenticated_Users
,
354 p
->server_info
->ptok
)) {
355 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
357 DEBUGADD(3,(" - does not have sid for Authenticated "
360 &global_sid_Authenticated_Users
)));
361 debug_nt_user_token(DBGC_CLASS
, 3,
362 p
->server_info
->ptok
);
363 return WERR_ACCESS_DENIED
;
365 r
->out
.info
->info101
= create_wks_info_101(p
->mem_ctx
);
366 if (r
->out
.info
->info101
== NULL
) {
371 /* Level 102 Should only be allowed from a domain administrator */
372 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
373 p
->server_info
->ptok
)) {
374 DEBUG(1,("User not allowed for NetWkstaGetInfo level "
376 DEBUGADD(3,(" - does not have sid for Administrators "
377 "group %s, sids are:\n",
378 sid_string_dbg(&global_sid_Builtin_Administrators
)));
379 debug_nt_user_token(DBGC_CLASS
, 3,
380 p
->server_info
->ptok
);
381 return WERR_ACCESS_DENIED
;
383 r
->out
.info
->info102
= create_wks_info_102(p
->mem_ctx
);
384 if (r
->out
.info
->info102
== NULL
) {
389 return WERR_UNKNOWN_LEVEL
;
395 /********************************************************************
396 ********************************************************************/
398 WERROR
_wkssvc_NetWkstaSetInfo(struct pipes_struct
*p
,
399 struct wkssvc_NetWkstaSetInfo
*r
)
401 /* FIXME: Add implementation code here */
402 p
->rng_fault_state
= True
;
403 return WERR_NOT_SUPPORTED
;
406 /********************************************************************
407 RPC Workstation Service request NetWkstaEnumUsers with level 0:
408 Returns to the requester:
409 - the user names of the logged in users.
410 Returns a filled in wkssvc_NetWkstaEnumUsersCtr0 struct.
411 ********************************************************************/
413 static struct wkssvc_NetWkstaEnumUsersCtr0
*create_enum_users0(
416 struct wkssvc_NetWkstaEnumUsersCtr0
*ctr0
;
420 ctr0
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr0
);
425 users
= get_logged_on_userlist(talloc_tos());
426 if (users
== NULL
&& errno
!= 0) {
427 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
428 errno
, strerror(errno
)));
433 num_users
= talloc_array_length(users
);
434 ctr0
->entries_read
= num_users
;
435 ctr0
->user0
= talloc_array(ctr0
, struct wkssvc_NetrWkstaUserInfo0
,
437 if (ctr0
->user0
== NULL
) {
443 for (i
=0; i
<num_users
; i
++) {
444 ctr0
->user0
[i
].user_name
= talloc_move(ctr0
->user0
, &users
[i
]);
450 /********************************************************************
451 RPC Workstation Service request NetWkstaEnumUsers with level 1.
452 Returns to the requester:
453 - the user names of the logged in users,
454 - the domain or machine each is logged into,
455 - the password server that was used to authenticate each,
456 - other domains each user is logged into (not currently supported).
457 Returns a filled in wkssvc_NetWkstaEnumUsersCtr1 struct.
458 ********************************************************************/
460 static struct wkssvc_NetWkstaEnumUsersCtr1
*create_enum_users1(
463 struct wkssvc_NetWkstaEnumUsersCtr1
*ctr1
;
465 struct dom_usr
*dom_users
;
466 const char *pwd_server
;
468 int i
, j
, num_users
, num_dom_users
;
470 ctr1
= talloc(mem_ctx
, struct wkssvc_NetWkstaEnumUsersCtr1
);
475 users
= get_logged_on_userlist(talloc_tos());
476 if (users
== NULL
&& errno
!= 0) {
477 DEBUG(1,("get_logged_on_userlist error %d: %s\n",
478 errno
, strerror(errno
)));
482 num_users
= talloc_array_length(users
);
484 dom_users
= get_domain_userlist(talloc_tos());
485 if (dom_users
== NULL
&& errno
!= 0) {
490 num_dom_users
= talloc_array_length(dom_users
);
492 ctr1
->user1
= talloc_array(ctr1
, struct wkssvc_NetrWkstaUserInfo1
,
493 num_users
+num_dom_users
);
494 if (ctr1
->user1
== NULL
) {
497 TALLOC_FREE(dom_users
);
503 if ((pwd_tmp
= talloc_strdup(ctr1
->user1
, lp_passwordserver()))) {
504 /* The configured password server is a full DNS name but
505 * for the logon server we need to return just the first
506 * component (machine name) of it in upper-case */
507 char *p
= strchr(pwd_tmp
, '.');
511 p
= pwd_tmp
+ strlen(pwd_tmp
);
513 while (--p
>= pwd_tmp
) {
516 pwd_server
= pwd_tmp
;
519 /* Put in local users first */
520 for (i
=0; i
<num_users
; i
++) {
521 ctr1
->user1
[i
].user_name
= talloc_move(ctr1
->user1
, &users
[i
]);
523 /* For a local user the domain name and logon server are
524 * both returned as the local machine's NetBIOS name */
525 ctr1
->user1
[i
].logon_domain
= ctr1
->user1
[i
].logon_server
=
526 talloc_asprintf_strupper_m(ctr1
->user1
, "%s", global_myname());
528 ctr1
->user1
[i
].other_domains
= NULL
; /* Maybe in future? */
531 /* Now domain users */
532 for (j
=0; j
<num_dom_users
; j
++) {
533 ctr1
->user1
[i
].user_name
=
534 talloc_strdup(ctr1
->user1
, dom_users
[j
].name
);
535 ctr1
->user1
[i
].logon_domain
=
536 talloc_strdup(ctr1
->user1
, dom_users
[j
].domain
);
537 ctr1
->user1
[i
].logon_server
= pwd_server
;
539 ctr1
->user1
[i
++].other_domains
= NULL
; /* Maybe in future? */
542 ctr1
->entries_read
= i
;
545 TALLOC_FREE(dom_users
);
549 /********************************************************************
550 Handling for RPC Workstation Service request NetWkstaEnumUsers
551 (a.k.a Windows NetWkstaUserEnum)
552 ********************************************************************/
554 WERROR
_wkssvc_NetWkstaEnumUsers(struct pipes_struct
*p
,
555 struct wkssvc_NetWkstaEnumUsers
*r
)
557 /* This with any level should only be allowed from a domain administrator */
558 if (!nt_token_check_sid(&global_sid_Builtin_Administrators
,
559 p
->server_info
->ptok
)) {
560 DEBUG(1,("User not allowed for NetWkstaEnumUsers\n"));
561 DEBUGADD(3,(" - does not have sid for Administrators group "
562 "%s\n", sid_string_dbg(
563 &global_sid_Builtin_Administrators
)));
564 debug_nt_user_token(DBGC_CLASS
, 3, p
->server_info
->ptok
);
565 return WERR_ACCESS_DENIED
;
568 switch (r
->in
.info
->level
) {
570 r
->out
.info
->ctr
.user0
= create_enum_users0(p
->mem_ctx
);
571 if (r
->out
.info
->ctr
.user0
== NULL
) {
574 r
->out
.info
->level
= r
->in
.info
->level
;
575 *r
->out
.entries_read
= r
->out
.info
->ctr
.user0
->entries_read
;
576 *r
->out
.resume_handle
= 0;
579 r
->out
.info
->ctr
.user1
= create_enum_users1(p
->mem_ctx
);
580 if (r
->out
.info
->ctr
.user1
== NULL
) {
583 r
->out
.info
->level
= r
->in
.info
->level
;
584 *r
->out
.entries_read
= r
->out
.info
->ctr
.user1
->entries_read
;
585 *r
->out
.resume_handle
= 0;
588 return WERR_UNKNOWN_LEVEL
;
594 /********************************************************************
595 ********************************************************************/
597 WERROR
_wkssvc_NetrWkstaUserGetInfo(struct pipes_struct
*p
,
598 struct wkssvc_NetrWkstaUserGetInfo
*r
)
600 /* FIXME: Add implementation code here */
601 p
->rng_fault_state
= True
;
602 return WERR_NOT_SUPPORTED
;
605 /********************************************************************
606 ********************************************************************/
608 WERROR
_wkssvc_NetrWkstaUserSetInfo(struct pipes_struct
*p
,
609 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(struct pipes_struct
*p
,
620 struct wkssvc_NetWkstaTransportEnum
*r
)
622 /* FIXME: Add implementation code here */
623 p
->rng_fault_state
= True
;
624 return WERR_NOT_SUPPORTED
;
627 /********************************************************************
628 ********************************************************************/
630 WERROR
_wkssvc_NetrWkstaTransportAdd(struct pipes_struct
*p
,
631 struct wkssvc_NetrWkstaTransportAdd
*r
)
633 /* FIXME: Add implementation code here */
634 p
->rng_fault_state
= True
;
635 return WERR_NOT_SUPPORTED
;
638 /********************************************************************
639 ********************************************************************/
641 WERROR
_wkssvc_NetrWkstaTransportDel(struct pipes_struct
*p
,
642 struct wkssvc_NetrWkstaTransportDel
*r
)
644 /* FIXME: Add implementation code here */
645 p
->rng_fault_state
= True
;
646 return WERR_NOT_SUPPORTED
;
649 /********************************************************************
650 ********************************************************************/
652 WERROR
_wkssvc_NetrUseAdd(struct pipes_struct
*p
,
653 struct wkssvc_NetrUseAdd
*r
)
655 /* FIXME: Add implementation code here */
656 p
->rng_fault_state
= True
;
657 return WERR_NOT_SUPPORTED
;
660 /********************************************************************
661 ********************************************************************/
663 WERROR
_wkssvc_NetrUseGetInfo(struct pipes_struct
*p
,
664 struct wkssvc_NetrUseGetInfo
*r
)
666 /* FIXME: Add implementation code here */
667 p
->rng_fault_state
= True
;
668 return WERR_NOT_SUPPORTED
;
671 /********************************************************************
672 ********************************************************************/
674 WERROR
_wkssvc_NetrUseDel(struct pipes_struct
*p
,
675 struct wkssvc_NetrUseDel
*r
)
677 /* FIXME: Add implementation code here */
678 p
->rng_fault_state
= True
;
679 return WERR_NOT_SUPPORTED
;
682 /********************************************************************
683 ********************************************************************/
685 WERROR
_wkssvc_NetrUseEnum(struct pipes_struct
*p
,
686 struct wkssvc_NetrUseEnum
*r
)
688 /* FIXME: Add implementation code here */
689 p
->rng_fault_state
= True
;
690 return WERR_NOT_SUPPORTED
;
693 /********************************************************************
694 ********************************************************************/
696 WERROR
_wkssvc_NetrMessageBufferSend(struct pipes_struct
*p
,
697 struct wkssvc_NetrMessageBufferSend
*r
)
699 /* FIXME: Add implementation code here */
700 p
->rng_fault_state
= True
;
701 return WERR_NOT_SUPPORTED
;
704 /********************************************************************
705 ********************************************************************/
707 WERROR
_wkssvc_NetrWorkstationStatisticsGet(struct pipes_struct
*p
,
708 struct wkssvc_NetrWorkstationStatisticsGet
*r
)
710 /* FIXME: Add implementation code here */
711 p
->rng_fault_state
= True
;
712 return WERR_NOT_SUPPORTED
;
715 /********************************************************************
716 ********************************************************************/
718 WERROR
_wkssvc_NetrLogonDomainNameAdd(struct pipes_struct
*p
,
719 struct wkssvc_NetrLogonDomainNameAdd
*r
)
721 /* FIXME: Add implementation code here */
722 p
->rng_fault_state
= True
;
723 return WERR_NOT_SUPPORTED
;
726 /********************************************************************
727 ********************************************************************/
729 WERROR
_wkssvc_NetrLogonDomainNameDel(struct pipes_struct
*p
,
730 struct wkssvc_NetrLogonDomainNameDel
*r
)
732 /* FIXME: Add implementation code here */
733 p
->rng_fault_state
= True
;
734 return WERR_NOT_SUPPORTED
;
737 /********************************************************************
738 ********************************************************************/
740 WERROR
_wkssvc_NetrJoinDomain(struct pipes_struct
*p
,
741 struct wkssvc_NetrJoinDomain
*r
)
743 /* FIXME: Add implementation code here */
744 p
->rng_fault_state
= True
;
745 return WERR_NOT_SUPPORTED
;
748 /********************************************************************
749 ********************************************************************/
751 WERROR
_wkssvc_NetrUnjoinDomain(struct pipes_struct
*p
,
752 struct wkssvc_NetrUnjoinDomain
*r
)
754 /* FIXME: Add implementation code here */
755 p
->rng_fault_state
= True
;
756 return WERR_NOT_SUPPORTED
;
759 /********************************************************************
760 ********************************************************************/
762 WERROR
_wkssvc_NetrRenameMachineInDomain(struct pipes_struct
*p
,
763 struct wkssvc_NetrRenameMachineInDomain
*r
)
765 /* FIXME: Add implementation code here */
766 p
->rng_fault_state
= True
;
767 return WERR_NOT_SUPPORTED
;
770 /********************************************************************
771 ********************************************************************/
773 WERROR
_wkssvc_NetrValidateName(struct pipes_struct
*p
,
774 struct wkssvc_NetrValidateName
*r
)
776 /* FIXME: Add implementation code here */
777 p
->rng_fault_state
= True
;
778 return WERR_NOT_SUPPORTED
;
781 /********************************************************************
782 ********************************************************************/
784 WERROR
_wkssvc_NetrGetJoinInformation(struct pipes_struct
*p
,
785 struct wkssvc_NetrGetJoinInformation
*r
)
787 /* FIXME: Add implementation code here */
788 p
->rng_fault_state
= True
;
789 return WERR_NOT_SUPPORTED
;
792 /********************************************************************
793 ********************************************************************/
795 WERROR
_wkssvc_NetrGetJoinableOus(struct pipes_struct
*p
,
796 struct wkssvc_NetrGetJoinableOus
*r
)
798 /* FIXME: Add implementation code here */
799 p
->rng_fault_state
= True
;
800 return WERR_NOT_SUPPORTED
;
803 /********************************************************************
804 _wkssvc_NetrJoinDomain2
805 ********************************************************************/
807 WERROR
_wkssvc_NetrJoinDomain2(struct pipes_struct
*p
,
808 struct wkssvc_NetrJoinDomain2
*r
)
810 struct libnet_JoinCtx
*j
= NULL
;
811 char *cleartext_pwd
= NULL
;
812 char *admin_domain
= NULL
;
813 char *admin_account
= NULL
;
815 struct nt_user_token
*token
= p
->server_info
->ptok
;
817 if (!r
->in
.domain_name
) {
818 return WERR_INVALID_PARAM
;
821 if (!r
->in
.admin_account
|| !r
->in
.encrypted_password
) {
822 return WERR_INVALID_PARAM
;
825 if (!user_has_privileges(token
, &se_machine_account
) &&
826 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
827 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
828 DEBUG(5,("_wkssvc_NetrJoinDomain2: account doesn't have "
829 "sufficient privileges\n"));
830 return WERR_ACCESS_DENIED
;
833 if ((r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED
) ||
834 (r
->in
.join_flags
& WKSSVC_JOIN_FLAGS_JOIN_UNSECURE
)) {
835 return WERR_NOT_SUPPORTED
;
838 werr
= decode_wkssvc_join_password_buffer(
839 p
->mem_ctx
, r
->in
.encrypted_password
,
840 &p
->server_info
->user_session_key
, &cleartext_pwd
);
841 if (!W_ERROR_IS_OK(werr
)) {
845 split_domain_user(p
->mem_ctx
,
850 werr
= libnet_init_JoinCtx(p
->mem_ctx
, &j
);
851 if (!W_ERROR_IS_OK(werr
)) {
855 j
->in
.domain_name
= r
->in
.domain_name
;
856 j
->in
.account_ou
= r
->in
.account_ou
;
857 j
->in
.join_flags
= r
->in
.join_flags
;
858 j
->in
.admin_account
= admin_account
;
859 j
->in
.admin_password
= cleartext_pwd
;
861 j
->in
.modify_config
= lp_config_backend_is_registry();
862 j
->in
.msg_ctx
= p
->msg_ctx
;
865 werr
= libnet_Join(p
->mem_ctx
, j
);
868 if (!W_ERROR_IS_OK(werr
)) {
869 DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n",
870 j
->out
.error_string
? j
->out
.error_string
:
878 /********************************************************************
879 _wkssvc_NetrUnjoinDomain2
880 ********************************************************************/
882 WERROR
_wkssvc_NetrUnjoinDomain2(struct pipes_struct
*p
,
883 struct wkssvc_NetrUnjoinDomain2
*r
)
885 struct libnet_UnjoinCtx
*u
= NULL
;
886 char *cleartext_pwd
= NULL
;
887 char *admin_domain
= NULL
;
888 char *admin_account
= NULL
;
890 struct nt_user_token
*token
= p
->server_info
->ptok
;
892 if (!r
->in
.account
|| !r
->in
.encrypted_password
) {
893 return WERR_INVALID_PARAM
;
896 if (!user_has_privileges(token
, &se_machine_account
) &&
897 !nt_token_check_domain_rid(token
, DOMAIN_RID_ADMINS
) &&
898 !nt_token_check_sid(&global_sid_Builtin_Administrators
, token
)) {
899 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: account doesn't have "
900 "sufficient privileges\n"));
901 return WERR_ACCESS_DENIED
;
904 werr
= decode_wkssvc_join_password_buffer(
905 p
->mem_ctx
, r
->in
.encrypted_password
,
906 &p
->server_info
->user_session_key
, &cleartext_pwd
);
907 if (!W_ERROR_IS_OK(werr
)) {
911 split_domain_user(p
->mem_ctx
,
916 werr
= libnet_init_UnjoinCtx(p
->mem_ctx
, &u
);
917 if (!W_ERROR_IS_OK(werr
)) {
921 u
->in
.domain_name
= lp_realm();
922 u
->in
.unjoin_flags
= r
->in
.unjoin_flags
|
923 WKSSVC_JOIN_FLAGS_JOIN_TYPE
;
924 u
->in
.admin_account
= admin_account
;
925 u
->in
.admin_password
= cleartext_pwd
;
927 u
->in
.modify_config
= lp_config_backend_is_registry();
928 u
->in
.msg_ctx
= p
->msg_ctx
;
931 werr
= libnet_Unjoin(p
->mem_ctx
, u
);
934 if (!W_ERROR_IS_OK(werr
)) {
935 DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n",
936 u
->out
.error_string
? u
->out
.error_string
:
944 /********************************************************************
945 ********************************************************************/
947 WERROR
_wkssvc_NetrRenameMachineInDomain2(struct pipes_struct
*p
,
948 struct wkssvc_NetrRenameMachineInDomain2
*r
)
950 /* for now just return not supported */
951 return WERR_NOT_SUPPORTED
;
954 /********************************************************************
955 ********************************************************************/
957 WERROR
_wkssvc_NetrValidateName2(struct pipes_struct
*p
,
958 struct wkssvc_NetrValidateName2
*r
)
960 /* FIXME: Add implementation code here */
961 p
->rng_fault_state
= True
;
962 return WERR_NOT_SUPPORTED
;
965 /********************************************************************
966 ********************************************************************/
968 WERROR
_wkssvc_NetrGetJoinableOus2(struct pipes_struct
*p
,
969 struct wkssvc_NetrGetJoinableOus2
*r
)
971 /* FIXME: Add implementation code here */
972 p
->rng_fault_state
= True
;
973 return WERR_NOT_SUPPORTED
;
976 /********************************************************************
977 ********************************************************************/
979 WERROR
_wkssvc_NetrAddAlternateComputerName(struct pipes_struct
*p
,
980 struct wkssvc_NetrAddAlternateComputerName
*r
)
982 /* FIXME: Add implementation code here */
983 p
->rng_fault_state
= True
;
984 return WERR_NOT_SUPPORTED
;
987 /********************************************************************
988 ********************************************************************/
990 WERROR
_wkssvc_NetrRemoveAlternateComputerName(struct pipes_struct
*p
,
991 struct wkssvc_NetrRemoveAlternateComputerName
*r
)
993 /* FIXME: Add implementation code here */
994 p
->rng_fault_state
= True
;
995 return WERR_NOT_SUPPORTED
;
998 /********************************************************************
999 ********************************************************************/
1001 WERROR
_wkssvc_NetrSetPrimaryComputername(struct pipes_struct
*p
,
1002 struct wkssvc_NetrSetPrimaryComputername
*r
)
1004 /* FIXME: Add implementation code here */
1005 p
->rng_fault_state
= True
;
1006 return WERR_NOT_SUPPORTED
;
1009 /********************************************************************
1010 ********************************************************************/
1012 WERROR
_wkssvc_NetrEnumerateComputerNames(struct pipes_struct
*p
,
1013 struct wkssvc_NetrEnumerateComputerNames
*r
)
1015 /* FIXME: Add implementation code here */
1016 p
->rng_fault_state
= True
;
1017 return WERR_NOT_SUPPORTED
;