2001-11-25 03:18:11 +03:00
/*
Samba Unix / Linux SMB client library
Version 3.0
net ads commands
Copyright ( C ) 2001 Andrew Tridgell ( tridge @ samba . org )
2001-12-20 06:54:52 +03:00
Copyright ( C ) 2001 Remus Koos ( remuskoos @ yahoo . com )
2001-11-25 03:18:11 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
# ifdef HAVE_ADS
2001-11-26 07:53:08 +03:00
int net_ads_usage ( int argc , const char * * argv )
2001-11-25 03:18:11 +03:00
{
d_printf (
2001-12-17 14:16:22 +03:00
" \n net ads join <org_unit> " \
2001-11-25 03:18:11 +03:00
" \n \t joins the local machine to a ADS realm \n " \
" \n net ads leave " \
2001-11-25 04:42:29 +03:00
" \n \t removes the local machine from a ADS realm \n " \
" \n net ads user " \
" \n \t list users in the realm \n " \
" \n net ads group " \
" \n \t list groups in the realm \n " \
2001-12-13 16:19:20 +03:00
" \n net ads info " \
" \n \t shows some info on the server \n " \
2001-11-25 04:42:29 +03:00
" \n net ads status " \
" \n \t dump the machine account details to stdout \n "
2001-12-20 06:54:52 +03:00
" \n net ads password <username@realm> -Uadmin_username@realm%%admin_pass " \
" \n \t change a user's password using an admin account "
" \n \t (note: use realm in UPPERCASE) \n "
" \n net ads chostpass "
" \n \t change the trust account password of this machine in the AD tree \n "
2001-11-25 03:18:11 +03:00
) ;
return - 1 ;
}
2001-12-13 16:19:20 +03:00
static int net_ads_info ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ads = ads_init ( NULL , NULL , NULL , NULL ) ;
ads_connect ( ads ) ;
if ( ! ads ) {
d_printf ( " Didn't find the ldap server! \n " ) ;
return - 1 ;
}
d_printf ( " LDAP server: %s \n " , ads - > ldap_server ) ;
d_printf ( " LDAP server name: %s \n " , ads - > ldap_server_name ) ;
d_printf ( " Realm: %s \n " , ads - > realm ) ;
d_printf ( " Bind Path: %s \n " , ads - > bind_path ) ;
d_printf ( " LDAP port: %d \n " , ads - > ldap_port ) ;
return 0 ;
}
2001-11-25 04:31:07 +03:00
static ADS_STRUCT * ads_startup ( void )
2001-11-25 03:18:11 +03:00
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS status ;
2001-12-08 14:18:56 +03:00
extern char * opt_password ;
extern char * opt_user_name ;
2001-12-05 12:46:53 +03:00
ads = ads_init ( NULL , NULL , NULL , NULL ) ;
2001-11-25 04:06:56 +03:00
2001-12-08 14:18:56 +03:00
if ( ! opt_user_name ) {
opt_user_name = " administrator " ;
}
if ( ! opt_password ) {
char * prompt ;
asprintf ( & prompt , " %s password: " , opt_user_name ) ;
opt_password = getpass ( prompt ) ;
free ( prompt ) ;
}
ads - > password = strdup ( opt_password ) ;
ads - > user_name = strdup ( opt_user_name ) ;
2001-12-19 15:21:12 +03:00
status = ads_connect ( ads ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( " ads_connect: %s \n " , ads_errstr ( status ) ) ;
2001-11-25 04:31:07 +03:00
return NULL ;
}
return ads ;
}
static int net_ads_user ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 04:31:07 +03:00
void * res ;
const char * attrs [ ] = { " sAMAccountName " , " name " , " objectSid " , NULL } ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
rc = ads_search ( ads , & res , " (objectclass=user) " , attrs ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-11-25 04:31:07 +03:00
d_printf ( " ads_search: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
d_printf ( " No users found \n " ) ;
return - 1 ;
}
ads_dump ( ads , res ) ;
2001-11-29 09:21:56 +03:00
ads_destroy ( & ads ) ;
2001-11-25 04:31:07 +03:00
return 0 ;
}
static int net_ads_group ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 04:31:07 +03:00
void * res ;
const char * attrs [ ] = { " sAMAccountName " , " name " , " objectSid " , NULL } ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
rc = ads_search ( ads , & res , " (objectclass=group) " , attrs ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-11-25 04:31:07 +03:00
d_printf ( " ads_search: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
d_printf ( " No groups found \n " ) ;
2001-11-25 04:06:56 +03:00
return - 1 ;
}
2001-11-25 03:18:11 +03:00
2001-11-25 04:31:07 +03:00
ads_dump ( ads , res ) ;
return 0 ;
}
static int net_ads_status ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 04:31:07 +03:00
extern pstring global_myname ;
void * res ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2001-11-25 04:06:56 +03:00
rc = ads_find_machine_acct ( ads , & res , global_myname ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-11-25 04:06:56 +03:00
d_printf ( " ads_find_machine_acct: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
d_printf ( " No machine account for '%s' found \n " , global_myname ) ;
return - 1 ;
}
ads_dump ( ads , res ) ;
return 0 ;
}
static int net_ads_leave ( int argc , const char * * argv )
{
2001-12-17 14:16:22 +03:00
ADS_STRUCT * ads = NULL ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 04:06:56 +03:00
extern pstring global_myname ;
2001-11-25 03:18:11 +03:00
2001-12-17 14:16:22 +03:00
if ( ! ( ads = ads_startup ( ) ) ) {
return - 1 ;
}
2001-11-25 04:31:07 +03:00
2001-11-25 03:18:11 +03:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
return - 1 ;
}
2001-11-25 04:06:56 +03:00
rc = ads_leave_realm ( ads , global_myname ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-11-25 03:18:11 +03:00
d_printf ( " Failed to delete host '%s' from the '%s' realm. \n " ,
2001-11-25 04:06:56 +03:00
global_myname , ads - > realm ) ;
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2001-11-25 04:06:56 +03:00
d_printf ( " Removed '%s' from realm '%s' \n " , global_myname , ads - > realm ) ;
2001-11-25 03:18:11 +03:00
return 0 ;
}
static int net_ads_join ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 03:18:11 +03:00
char * password ;
2001-12-05 04:58:33 +03:00
char * tmp_password ;
2001-11-25 03:18:11 +03:00
extern pstring global_myname ;
2001-12-17 14:16:22 +03:00
const char * org_unit = " Computers " ;
char * dn ;
void * res ;
2001-12-21 02:35:53 +03:00
DOM_SID dom_sid ;
2001-12-17 14:16:22 +03:00
if ( argc > 0 ) org_unit = argv [ 0 ] ;
2001-11-25 03:18:11 +03:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
return - 1 ;
}
2001-12-17 14:16:22 +03:00
2001-12-05 14:00:26 +03:00
tmp_password = generate_random_str ( DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH ) ;
2001-12-05 04:58:33 +03:00
password = strdup ( tmp_password ) ;
2001-11-25 03:18:11 +03:00
2001-11-25 04:31:07 +03:00
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2001-11-25 03:18:11 +03:00
2001-12-17 14:16:22 +03:00
asprintf ( & dn , " cn=%s,%s " , org_unit , ads - > bind_path ) ;
rc = ads_search_dn ( ads , & res , dn , NULL ) ;
free ( dn ) ;
ads_msgfree ( ads , res ) ;
2001-12-19 15:21:12 +03:00
if ( rc . error_type = = ADS_ERROR_LDAP & & rc . rc = = LDAP_NO_SUCH_OBJECT ) {
2001-12-17 14:16:22 +03:00
d_printf ( " ads_join_realm: organisational unit %s does not exist \n " , org_unit ) ;
2001-12-19 15:21:12 +03:00
return - 1 ;
2001-12-17 14:16:22 +03:00
}
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-12-17 14:16:22 +03:00
d_printf ( " ads_join_realm: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
rc = ads_join_realm ( ads , global_myname , org_unit ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2001-11-25 03:18:11 +03:00
d_printf ( " ads_join_realm: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
2001-12-19 15:21:12 +03:00
rc = ads_set_machine_password ( ads , global_myname , password ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_set_machine_password: %s \n " , ads_errstr ( rc ) ) ;
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2001-12-21 02:35:53 +03:00
rc = ads_domain_sid ( ads , & dom_sid ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_domain_sid: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
if ( ! secrets_store_domain_sid ( lp_workgroup ( ) , & dom_sid ) ) {
DEBUG ( 1 , ( " Failed to save domain sid \n " ) ) ;
return - 1 ;
}
2001-11-25 03:18:11 +03:00
if ( ! secrets_store_machine_password ( password ) ) {
DEBUG ( 1 , ( " Failed to save machine password \n " ) ) ;
return - 1 ;
}
2001-11-25 04:06:56 +03:00
d_printf ( " Joined '%s' to realm '%s' \n " , global_myname , ads - > realm ) ;
2001-11-25 03:18:11 +03:00
2001-11-25 04:36:02 +03:00
free ( password ) ;
2001-11-25 03:18:11 +03:00
return 0 ;
}
2001-12-20 06:54:52 +03:00
static int net_ads_password ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
extern char * opt_user_name ;
extern char * opt_password ;
char * auth_principal = opt_user_name ;
char * auth_password = opt_password ;
char * realm = NULL ;
char * new_password = NULL ;
char * c ;
char * prompt ;
ADS_STATUS ret ;
if ( ( argc ! = 1 ) | | ( opt_user_name = = NULL ) | |
( opt_password = = NULL ) | | ( strchr ( opt_user_name , ' @ ' ) = = NULL ) | |
( strchr ( argv [ 0 ] , ' @ ' ) = = NULL ) ) {
return net_ads_usage ( argc , argv ) ;
}
c = strchr ( auth_principal , ' @ ' ) ;
realm = + + c ;
/* use the realm so we can eventually change passwords for users
in realms other than default */
if ( ! ( ads = ads_init ( realm , NULL , NULL , NULL ) ) ) return - 1 ;
asprintf ( & prompt , " Enter new password for %s: " , argv [ 0 ] ) ;
new_password = getpass ( prompt ) ;
ret = kerberos_set_password ( ads - > kdc_server , auth_principal ,
auth_password , argv [ 0 ] , new_password ) ;
if ( ! ADS_ERR_OK ( ret ) ) {
d_printf ( " Password change failed :-( ... \n " ) ;
ads_destroy ( & ads ) ;
free ( prompt ) ;
return - 1 ;
}
d_printf ( " Password change for %s completed. \n " , argv [ 0 ] ) ;
ads_destroy ( & ads ) ;
free ( prompt ) ;
return 0 ;
}
static int net_ads_change_localhost_pass ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
extern pstring global_myname ;
char * host_principal ;
char * hostname ;
ADS_STATUS ret ;
if ( ! ( ads = ads_init ( NULL , NULL , NULL , NULL ) ) ) return - 1 ;
hostname = strdup ( global_myname ) ;
strlower ( hostname ) ;
asprintf ( & host_principal , " %s@%s " , hostname , ads - > realm ) ;
SAFE_FREE ( hostname ) ;
d_printf ( " Changing password for principal: HOST/%s \n " , host_principal ) ;
ret = ads_change_trust_account_password ( ads , host_principal ) ;
if ( ! ADS_ERR_OK ( ret ) ) {
d_printf ( " Password change failed :-( ... \n " ) ;
ads_destroy ( & ads ) ;
SAFE_FREE ( host_principal ) ;
return - 1 ;
}
d_printf ( " Password change for principal HOST/%s succeeded. \n " , host_principal ) ;
ads_destroy ( & ads ) ;
SAFE_FREE ( host_principal ) ;
return 0 ;
}
2001-11-25 03:18:11 +03:00
int net_ads ( int argc , const char * * argv )
{
struct functable func [ ] = {
2001-12-13 16:19:20 +03:00
{ " INFO " , net_ads_info } ,
2001-11-25 03:18:11 +03:00
{ " JOIN " , net_ads_join } ,
{ " LEAVE " , net_ads_leave } ,
2001-11-25 04:06:56 +03:00
{ " STATUS " , net_ads_status } ,
2001-11-25 04:31:07 +03:00
{ " USER " , net_ads_user } ,
{ " GROUP " , net_ads_group } ,
2001-12-20 06:54:52 +03:00
{ " PASSWORD " , net_ads_password } ,
{ " CHOSTPASS " , net_ads_change_localhost_pass } ,
2001-11-25 03:18:11 +03:00
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_ads_usage ) ;
}
# else
2001-11-26 07:53:08 +03:00
int net_ads_usage ( int argc , const char * * argv )
2001-11-25 03:18:11 +03:00
{
d_printf ( " ADS support not compiled in \n " ) ;
return - 1 ;
}
int net_ads ( int argc , const char * * argv )
{
2001-11-26 07:53:08 +03:00
return net_ads_usage ( argc , argv ) ;
2001-11-25 03:18:11 +03:00
}
# endif