2001-11-25 03:18:11 +03:00
/*
Samba Unix / Linux SMB client library
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 )
2002-02-02 05:06:03 +03:00
Copyright ( C ) 2002 Jim McDonough ( jmcd @ us . ibm . 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"
2002-04-10 17:29:23 +04:00
# include "../utils/net.h"
2001-11-25 03:18:11 +03:00
# 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 " \
2002-08-17 18:45:04 +04:00
" \n net ads testjoin " \
" \n \t tests that an exiting join is OK \n " \
2001-11-25 04:42:29 +03:00
" \n net ads user " \
2002-07-15 14:35:28 +04:00
" \n \t list, add, or delete users in the realm \n " \
2001-11-25 04:42:29 +03:00
" \n net ads group " \
2002-07-15 14:35:28 +04:00
" \n \t list, add, or delete 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 "
2003-01-15 21:57:41 +03:00
" \n net ads lookup " \
" \n \t perform a CLDAP search on the server \n "
2001-12-20 06:54:52 +03:00
" \n net ads password <username@realm> -Uadmin_username@realm%%admin_pass " \
2002-07-15 14:35:28 +04:00
" \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 " \
" \n net ads printer [info | publish | remove] <printername> <servername> " \
" \n \t lookup, add, or remove directory entry for a printer \n " \
" \n net ads search " \
" \n \t perform a raw LDAP search and dump the results \n "
2001-11-25 03:18:11 +03:00
) ;
return - 1 ;
}
2001-12-13 16:19:20 +03:00
2002-09-25 19:19:00 +04:00
/*
this implements the CLDAP based netlogon lookup requests
for finding the domain controller of a ADS domain
*/
static int net_ads_lookup ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ads = ads_init ( NULL , NULL , opt_host ) ;
if ( ads ) {
ads - > auth . flags | = ADS_AUTH_NO_BIND ;
}
ads_connect ( ads ) ;
if ( ! ads | | ! ads - > config . realm ) {
d_printf ( " Didn't find the cldap server! \n " ) ;
return - 1 ;
}
return ads_cldap_netlogon ( ads ) ;
}
2001-12-13 16:19:20 +03:00
static int net_ads_info ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2002-08-17 18:45:04 +04:00
ads = ads_init ( NULL , NULL , opt_host ) ;
if ( ads ) {
2002-09-25 19:19:00 +04:00
ads - > auth . flags | = ADS_AUTH_NO_BIND ;
2002-08-17 18:45:04 +04:00
}
2001-12-13 16:19:20 +03:00
ads_connect ( ads ) ;
2002-08-17 18:45:04 +04:00
if ( ! ads | | ! ads - > config . realm ) {
2001-12-13 16:19:20 +03:00
d_printf ( " Didn't find the ldap server! \n " ) ;
return - 1 ;
}
2002-08-17 18:45:04 +04:00
d_printf ( " LDAP server: %s \n " , inet_ntoa ( ads - > ldap_ip ) ) ;
d_printf ( " LDAP server name: %s \n " , ads - > config . ldap_server_name ) ;
d_printf ( " Realm: %s \n " , ads - > config . realm ) ;
d_printf ( " Bind Path: %s \n " , ads - > config . bind_path ) ;
2001-12-13 16:19:20 +03:00
d_printf ( " LDAP port: %d \n " , ads - > ldap_port ) ;
2002-09-25 19:19:00 +04:00
d_printf ( " Server time: %s \n " , http_timestring ( ads - > config . current_time ) ) ;
2001-12-13 16:19:20 +03:00
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 ;
2002-01-26 01:07:46 +03:00
BOOL need_password = False ;
BOOL second_time = False ;
2002-03-21 07:48:24 +03:00
2002-08-17 18:45:04 +04:00
ads = ads_init ( NULL , NULL , opt_host ) ;
2001-11-25 04:06:56 +03:00
2001-12-08 14:18:56 +03:00
if ( ! opt_user_name ) {
opt_user_name = " administrator " ;
}
2002-01-26 01:07:46 +03:00
if ( opt_user_specified )
need_password = True ;
retry :
if ( ! opt_password & & need_password ) {
2001-12-08 14:18:56 +03:00
char * prompt ;
asprintf ( & prompt , " %s password: " , opt_user_name ) ;
opt_password = getpass ( prompt ) ;
free ( prompt ) ;
}
2002-01-26 01:07:46 +03:00
2002-02-17 01:11:49 +03:00
if ( opt_password )
2002-08-17 18:45:04 +04:00
ads - > auth . password = strdup ( opt_password ) ;
2002-02-17 01:11:49 +03:00
2002-08-17 18:45:04 +04:00
ads - > auth . user_name = strdup ( opt_user_name ) ;
2001-12-08 14:18:56 +03:00
2001-12-19 15:21:12 +03:00
status = ads_connect ( ads ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2002-01-26 01:07:46 +03:00
if ( ! need_password & & ! second_time ) {
need_password = True ;
second_time = True ;
goto retry ;
} else {
2002-04-04 20:47:24 +04:00
DEBUG ( 1 , ( " ads_connect: %s \n " , ads_errstr ( status ) ) ) ;
2002-01-26 01:07:46 +03:00
return NULL ;
}
2001-11-25 04:31:07 +03:00
}
return ads ;
}
2002-04-04 20:47:24 +04:00
/*
Check to see if connection can be made via ads .
ads_startup ( ) stores the password in opt_password if it needs to so
that rpc or rap can use it without re - prompting .
*/
int net_ads_check ( void )
{
ADS_STRUCT * ads ;
ads = ads_startup ( ) ;
if ( ! ads )
return - 1 ;
ads_destroy ( & ads ) ;
return 0 ;
}
2002-08-17 18:45:04 +04:00
/*
determine the netbios workgroup name for a domain
*/
static int net_ads_workgroup ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
TALLOC_CTX * ctx ;
char * workgroup ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2002-12-20 23:21:31 +03:00
if ( ! ( ctx = talloc_init ( " net_ads_workgroup " ) ) ) {
2002-08-17 18:45:04 +04:00
return - 1 ;
}
if ( ! ADS_ERR_OK ( ads_workgroup_name ( ads , ctx , & workgroup ) ) ) {
d_printf ( " Failed to find workgroup for realm '%s' \n " ,
ads - > config . realm ) ;
talloc_destroy ( ctx ) ;
return - 1 ;
}
2002-04-04 20:47:24 +04:00
2002-08-17 18:45:04 +04:00
d_printf ( " Workgroup: %s \n " , workgroup ) ;
talloc_destroy ( ctx ) ;
return 0 ;
}
2002-09-25 19:19:00 +04:00
static BOOL usergrp_display ( char * field , void * * values , void * data_area )
2002-03-30 00:09:44 +03:00
{
char * * disp_fields = ( char * * ) data_area ;
if ( ! field ) { /* must be end of record */
2002-04-05 23:28:02 +04:00
if ( ! strchr_m ( disp_fields [ 0 ] , ' $ ' ) ) {
if ( disp_fields [ 1 ] )
2002-07-15 14:35:28 +04:00
d_printf ( " %-21.21s %-50.50s \n " ,
2002-04-05 23:28:02 +04:00
disp_fields [ 0 ] , disp_fields [ 1 ] ) ;
else
2002-07-15 14:35:28 +04:00
d_printf ( " %s \n " , disp_fields [ 0 ] ) ;
2002-04-05 23:28:02 +04:00
}
2002-03-30 00:09:44 +03:00
SAFE_FREE ( disp_fields [ 0 ] ) ;
SAFE_FREE ( disp_fields [ 1 ] ) ;
2002-09-25 19:19:00 +04:00
return True ;
2002-03-30 00:09:44 +03:00
}
2002-07-15 14:35:28 +04:00
if ( ! values ) /* must be new field, indicate string field */
2002-09-25 19:19:00 +04:00
return True ;
2002-03-30 00:09:44 +03:00
if ( StrCaseCmp ( field , " sAMAccountName " ) = = 0 ) {
2002-07-15 14:35:28 +04:00
disp_fields [ 0 ] = strdup ( ( char * ) values [ 0 ] ) ;
2002-03-30 00:09:44 +03:00
}
if ( StrCaseCmp ( field , " description " ) = = 0 )
2002-07-15 14:35:28 +04:00
disp_fields [ 1 ] = strdup ( ( char * ) values [ 0 ] ) ;
2002-09-25 19:19:00 +04:00
return True ;
2002-03-30 00:09:44 +03:00
}
2002-04-04 06:53:42 +04:00
static int net_ads_user_usage ( int argc , const char * * argv )
{
2002-04-05 05:36:28 +04:00
return net_help_user ( argc , argv ) ;
2002-04-04 06:53:42 +04:00
}
static int ads_user_add ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS status ;
2002-07-15 14:35:28 +04:00
char * upn , * userdn ;
2002-04-04 06:53:42 +04:00
void * res = NULL ;
int rc = - 1 ;
if ( argc < 1 ) return net_ads_user_usage ( argc , argv ) ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2002-04-04 07:06:22 +04:00
d_printf ( " ads_user_add: %s \n " , ads_errstr ( status ) ) ;
2002-04-04 06:53:42 +04:00
goto done ;
}
if ( ads_count_replies ( ads , res ) ) {
d_printf ( " ads_user_add: User %s already exists \n " , argv [ 0 ] ) ;
goto done ;
}
2003-01-15 19:10:57 +03:00
status = ads_add_user_acct ( ads , argv [ 0 ] , opt_container , opt_comment ) ;
2002-04-04 06:53:42 +04:00
2002-07-15 14:35:28 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( " Could not add user %s: %s \n " , argv [ 0 ] ,
ads_errstr ( status ) ) ;
goto done ;
}
/* if no password is to be set, we're done */
if ( argc = = 1 ) {
d_printf ( " User %s added \n " , argv [ 0 ] ) ;
rc = 0 ;
goto done ;
}
/* try setting the password */
2002-08-17 18:45:04 +04:00
asprintf ( & upn , " %s@%s " , argv [ 0 ] , ads - > config . realm ) ;
2002-09-25 19:19:00 +04:00
status = krb5_set_password ( ads - > auth . kdc_server , upn , argv [ 1 ] , ads - > auth . time_offset ) ;
2002-07-15 14:35:28 +04:00
safe_free ( upn ) ;
2002-04-04 06:53:42 +04:00
if ( ADS_ERR_OK ( status ) ) {
d_printf ( " User %s added \n " , argv [ 0 ] ) ;
rc = 0 ;
2002-07-15 14:35:28 +04:00
goto done ;
}
/* password didn't set, delete account */
d_printf ( " Could not add user %s. Error setting password %s \n " ,
argv [ 0 ] , ads_errstr ( status ) ) ;
ads_msgfree ( ads , res ) ;
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ADS_ERR_OK ( status ) ) {
userdn = ads_get_dn ( ads , res ) ;
ads_del_dn ( ads , userdn ) ;
ads_memfree ( ads , userdn ) ;
2002-04-04 06:53:42 +04:00
}
done :
if ( res )
ads_msgfree ( ads , res ) ;
ads_destroy ( & ads ) ;
return rc ;
}
static int ads_user_info ( int argc , const char * * argv )
2001-11-25 04:31:07 +03:00
{
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2001-11-25 04:31:07 +03:00
void * res ;
2002-04-04 06:53:42 +04:00
const char * attrs [ ] = { " memberOf " , NULL } ;
char * searchstring = NULL ;
char * * grouplist ;
2003-02-01 10:59:29 +03:00
char * escaped_user = escape_ldap_string_alloc ( argv [ 0 ] ) ;
2002-04-04 06:53:42 +04:00
if ( argc < 1 ) return net_ads_user_usage ( argc , argv ) ;
2002-03-14 20:56:33 +03:00
2001-11-25 04:31:07 +03:00
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2003-02-01 10:59:29 +03:00
if ( ! escaped_user ) {
d_printf ( " ads_user_info: failed to escape user %s \n " , argv [ 0 ] ) ;
return - 1 ;
}
asprintf ( & searchstring , " (sAMAccountName=%s) " , escaped_user ) ;
2002-04-04 06:53:42 +04:00
rc = ads_search ( ads , & res , searchstring , attrs ) ;
safe_free ( searchstring ) ;
2001-11-25 04:31:07 +03:00
2002-03-20 01:16:19 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_search: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
2002-03-30 00:09:44 +03:00
2002-04-04 06:53:42 +04:00
grouplist = ldap_get_values ( ads - > ld , res , " memberOf " ) ;
if ( grouplist ) {
int i ;
char * * groupname ;
for ( i = 0 ; grouplist [ i ] ; i + + ) {
groupname = ldap_explode_dn ( grouplist [ i ] , 1 ) ;
2002-07-15 14:35:28 +04:00
d_printf ( " %s \n " , groupname [ 0 ] ) ;
2002-04-04 06:53:42 +04:00
ldap_value_free ( groupname ) ;
}
ldap_value_free ( grouplist ) ;
}
2002-03-30 00:09:44 +03:00
ads_msgfree ( ads , res ) ;
2001-11-29 09:21:56 +03:00
ads_destroy ( & ads ) ;
2001-11-25 04:31:07 +03:00
return 0 ;
}
2002-04-04 06:53:42 +04:00
static int ads_user_delete ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
void * res ;
char * userdn ;
if ( argc < 1 ) return net_ads_user_usage ( argc , argv ) ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
rc = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
DEBUG ( 0 , ( " User %s does not exist \n " , argv [ 0 ] ) ) ;
return - 1 ;
}
userdn = ads_get_dn ( ads , res ) ;
ads_msgfree ( ads , res ) ;
rc = ads_del_dn ( ads , userdn ) ;
ads_memfree ( ads , userdn ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " User %s deleted \n " , argv [ 0 ] ) ;
return 0 ;
}
d_printf ( " Error deleting user %s: %s \n " , argv [ 0 ] ,
2002-04-04 07:06:22 +04:00
ads_errstr ( rc ) ) ;
2002-04-04 06:53:42 +04:00
return - 1 ;
}
2002-04-04 20:47:24 +04:00
int net_ads_user ( int argc , const char * * argv )
2002-04-04 06:53:42 +04:00
{
struct functable func [ ] = {
{ " ADD " , ads_user_add } ,
{ " INFO " , ads_user_info } ,
{ " DELETE " , ads_user_delete } ,
{ NULL , NULL }
} ;
ADS_STRUCT * ads ;
ADS_STATUS rc ;
const char * shortattrs [ ] = { " sAMAccountName " , NULL } ;
const char * longattrs [ ] = { " sAMAccountName " , " description " , NULL } ;
char * disp_fields [ 2 ] = { NULL , NULL } ;
if ( argc = = 0 ) {
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
if ( opt_long_list_entries )
d_printf ( " \n User name Comment " \
" \n ----------------------------- \n " ) ;
2002-08-17 18:45:04 +04:00
rc = ads_do_search_all_fn ( ads , ads - > config . bind_path ,
2002-04-10 17:29:23 +04:00
LDAP_SCOPE_SUBTREE ,
" (objectclass=user) " ,
opt_long_list_entries ? longattrs :
shortattrs , usergrp_display ,
disp_fields ) ;
2002-04-04 06:53:42 +04:00
ads_destroy ( & ads ) ;
return 0 ;
}
return net_run_function ( argc , argv , func , net_ads_user_usage ) ;
}
2002-07-15 14:35:28 +04:00
static int net_ads_group_usage ( int argc , const char * * argv )
{
return net_help_group ( argc , argv ) ;
}
static int ads_group_add ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS status ;
void * res = NULL ;
int rc = - 1 ;
if ( argc < 1 ) return net_ads_group_usage ( argc , argv ) ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( " ads_group_add: %s \n " , ads_errstr ( status ) ) ;
goto done ;
}
if ( ads_count_replies ( ads , res ) ) {
d_printf ( " ads_group_add: Group %s already exists \n " , argv [ 0 ] ) ;
ads_msgfree ( ads , res ) ;
goto done ;
}
2003-01-15 19:10:57 +03:00
status = ads_add_group_acct ( ads , argv [ 0 ] , opt_container , opt_comment ) ;
2002-07-15 14:35:28 +04:00
if ( ADS_ERR_OK ( status ) ) {
d_printf ( " Group %s added \n " , argv [ 0 ] ) ;
rc = 0 ;
} else {
d_printf ( " Could not add group %s: %s \n " , argv [ 0 ] ,
ads_errstr ( status ) ) ;
}
done :
if ( res )
ads_msgfree ( ads , res ) ;
ads_destroy ( & ads ) ;
return rc ;
}
static int ads_group_delete ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
void * res ;
char * groupdn ;
if ( argc < 1 ) return net_ads_group_usage ( argc , argv ) ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
rc = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
DEBUG ( 0 , ( " Group %s does not exist \n " , argv [ 0 ] ) ) ;
return - 1 ;
}
groupdn = ads_get_dn ( ads , res ) ;
ads_msgfree ( ads , res ) ;
rc = ads_del_dn ( ads , groupdn ) ;
ads_memfree ( ads , groupdn ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " Group %s deleted \n " , argv [ 0 ] ) ;
return 0 ;
}
d_printf ( " Error deleting group %s: %s \n " , argv [ 0 ] ,
ads_errstr ( rc ) ) ;
return - 1 ;
}
int net_ads_group ( int argc , const char * * argv )
2001-11-25 04:31:07 +03:00
{
2002-07-15 14:35:28 +04:00
struct functable func [ ] = {
{ " ADD " , ads_group_add } ,
{ " DELETE " , ads_group_delete } ,
{ NULL , NULL }
} ;
2001-11-25 04:31:07 +03:00
ADS_STRUCT * ads ;
2001-12-19 15:21:12 +03:00
ADS_STATUS rc ;
2002-03-30 00:09:44 +03:00
const char * shortattrs [ ] = { " sAMAccountName " , NULL } ;
const char * longattrs [ ] = { " sAMAccountName " , " description " , NULL } ;
char * disp_fields [ 2 ] = { NULL , NULL } ;
2001-11-25 04:31:07 +03:00
2002-07-15 14:35:28 +04:00
if ( argc = = 0 ) {
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2001-11-25 04:31:07 +03:00
2002-07-15 14:35:28 +04:00
if ( opt_long_list_entries )
d_printf ( " \n Group name Comment " \
" \n ----------------------------- \n " ) ;
2002-08-17 18:45:04 +04:00
rc = ads_do_search_all_fn ( ads , ads - > config . bind_path ,
2002-07-15 14:35:28 +04:00
LDAP_SCOPE_SUBTREE ,
" (objectclass=group) " ,
opt_long_list_entries ? longattrs :
shortattrs , usergrp_display ,
disp_fields ) ;
2002-03-30 00:09:44 +03:00
2002-07-15 14:35:28 +04:00
ads_destroy ( & ads ) ;
return 0 ;
}
return net_run_function ( argc , argv , func , net_ads_group_usage ) ;
2001-11-25 04:31:07 +03:00
}
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
void * res ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
2002-11-13 02:20:50 +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 ) {
2002-11-13 02:20:50 +03:00
d_printf ( " No machine account for '%s' found \n " , global_myname ( ) ) ;
2001-11-25 04:06:56 +03:00
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 03:18:11 +03:00
2002-03-10 04:52:09 +03:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
2001-12-17 14:16:22 +03:00
return - 1 ;
}
2001-11-25 04:31:07 +03:00
2002-03-10 04:52:09 +03:00
if ( ! opt_password ) {
2003-01-03 11:28:12 +03:00
char * user_name ;
asprintf ( & user_name , " %s$ " , global_myname ( ) ) ;
2002-03-10 04:52:09 +03:00
opt_password = secrets_fetch_machine_password ( ) ;
2003-01-03 11:28:12 +03:00
opt_user_name = user_name ;
2002-03-10 04:52:09 +03:00
}
if ( ! ( ads = ads_startup ( ) ) ) {
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2002-11-13 02:20:50 +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 " ,
2002-11-13 02:20:50 +03:00
global_myname ( ) , ads - > config . realm ) ;
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2002-11-13 02:20:50 +03:00
d_printf ( " Removed '%s' from realm '%s' \n " , global_myname ( ) , ads - > config . realm ) ;
2002-08-17 18:45:04 +04:00
return 0 ;
}
static int net_ads_join_ok ( void )
{
2003-01-03 11:28:12 +03:00
char * user_name ;
2002-08-17 18:45:04 +04:00
ADS_STRUCT * ads = NULL ;
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
return - 1 ;
}
2003-01-03 11:28:12 +03:00
asprintf ( & user_name , " %s$ " , global_myname ( ) ) ;
opt_user_name = user_name ;
2002-08-17 18:45:04 +04:00
opt_password = secrets_fetch_machine_password ( ) ;
2001-11-25 03:18:11 +03:00
2002-08-17 18:45:04 +04:00
if ( ! ( ads = ads_startup ( ) ) ) {
return - 1 ;
}
ads_destroy ( & ads ) ;
2001-11-25 03:18:11 +03:00
return 0 ;
}
2002-08-17 18:45:04 +04:00
/*
check that an existing join is OK
*/
int net_ads_testjoin ( int argc , const char * * argv )
{
/* Display success or failure */
if ( net_ads_join_ok ( ) ! = 0 ) {
fprintf ( stderr , " Join to domain is not valid \n " ) ;
return - 1 ;
}
printf ( " Join is OK \n " ) ;
return 0 ;
}
/*
join a domain using ADS
*/
2002-03-16 01:05:39 +03:00
int net_ads_join ( int argc , const char * * argv )
2001-11-25 03:18:11 +03:00
{
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-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 ;
2002-01-16 05:22:30 +03:00
char * ou_str ;
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
2002-01-16 05:22:30 +03:00
ou_str = ads_ou_string ( org_unit ) ;
2002-08-17 18:45:04 +04:00
asprintf ( & dn , " %s,%s " , ou_str , ads - > config . bind_path ) ;
2002-01-16 05:22:30 +03:00
free ( ou_str ) ;
2001-12-17 14:16:22 +03:00
rc = ads_search_dn ( ads , & res , dn , NULL ) ;
ads_msgfree ( ads , res ) ;
2002-09-25 19:19:00 +04:00
if ( rc . error_type = = ADS_ERROR_LDAP & & rc . err . rc = = LDAP_NO_SUCH_OBJECT ) {
2002-03-10 04:52:09 +03:00
d_printf ( " ads_join_realm: organizational unit %s does not exist (dn:%s) \n " ,
2002-01-16 05:22:30 +03:00
org_unit , dn ) ;
2001-12-19 15:21:12 +03:00
return - 1 ;
2001-12-17 14:16:22 +03:00
}
2002-01-16 05:22:30 +03:00
free ( dn ) ;
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 ;
}
2002-11-13 02:20:50 +03:00
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 ;
}
2002-09-25 19:19:00 +04:00
rc = ads_domain_sid ( ads , & dom_sid ) ;
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2002-09-25 19:19:00 +04:00
d_printf ( " ads_domain_sid: %s \n " , ads_errstr ( rc ) ) ;
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2002-11-13 02:20:50 +03:00
rc = ads_set_machine_password ( ads , global_myname ( ) , password ) ;
2001-12-21 02:35:53 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
2002-09-25 19:19:00 +04:00
d_printf ( " ads_set_machine_password: %s \n " , ads_errstr ( rc ) ) ;
2001-12-21 02:35:53 +03:00
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 ;
}
2002-11-13 02:20:50 +03:00
d_printf ( " Joined '%s' to realm '%s' \n " , global_myname ( ) , ads - > config . 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 ;
}
2002-02-02 05:06:03 +03:00
int net_ads_printer_usage ( int argc , const char * * argv )
{
d_printf (
" \n net ads printer info <printer> <server> "
" \n \t lookup info in directory for printer on server "
" \n \t (note: printer defaults to \" * \" , server defaults to local) \n "
" \n net ads printer publish <printername> "
" \n \t publish printer in directory "
" \n \t (note: printer name is required) \n "
" \n net ads printer remove <printername> "
" \n \t remove printer from directory "
" \n \t (note: printer name is required) \n " ) ;
return - 1 ;
}
static int net_ads_printer_info ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
2002-07-15 14:35:28 +04:00
const char * servername , * printername ;
2002-02-02 05:06:03 +03:00
void * res = NULL ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
if ( argc > 0 )
printername = argv [ 0 ] ;
else
printername = " * " ;
if ( argc > 1 )
servername = argv [ 1 ] ;
else
2002-11-13 02:20:50 +03:00
servername = global_myname ( ) ;
2002-02-02 05:06:03 +03:00
rc = ads_find_printer_on_server ( ads , & res , printername , servername ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_find_printer_on_server: %s \n " , ads_errstr ( rc ) ) ;
ads_msgfree ( ads , res ) ;
return - 1 ;
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
d_printf ( " Printer '%s' not found \n " , printername ) ;
ads_msgfree ( ads , res ) ;
return - 1 ;
}
ads_dump ( ads , res ) ;
2002-03-30 00:09:44 +03:00
ads_msgfree ( ads , res ) ;
2002-02-02 05:06:03 +03:00
return 0 ;
}
2002-07-15 14:35:28 +04:00
void do_drv_upgrade_printer ( int msg_type , pid_t src , void * buf , size_t len )
{
return ;
}
2002-02-02 05:06:03 +03:00
static int net_ads_printer_publish ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
2003-01-03 11:28:12 +03:00
const char * servername ;
2002-11-18 23:23:05 +03:00
struct cli_state * cli ;
struct in_addr server_ip ;
NTSTATUS nt_status ;
2002-12-20 23:21:31 +03:00
TALLOC_CTX * mem_ctx = talloc_init ( " net_ads_printer_publish " ) ;
2002-11-18 23:23:05 +03:00
ADS_MODLIST mods = ads_init_mods ( mem_ctx ) ;
char * prt_dn , * srv_dn , * * srv_cn ;
void * res = NULL ;
2002-02-02 05:06:03 +03:00
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
if ( argc < 1 )
return net_ads_printer_usage ( argc , argv ) ;
2002-11-18 23:23:05 +03:00
2002-11-23 05:51:28 +03:00
if ( argc = = 2 )
2002-11-18 23:23:05 +03:00
servername = argv [ 1 ] ;
else
servername = global_myname ( ) ;
ads_find_machine_acct ( ads , & res , servername ) ;
srv_dn = ldap_get_dn ( ads - > ld , res ) ;
srv_cn = ldap_explode_dn ( srv_dn , 1 ) ;
asprintf ( & prt_dn , " cn=%s-%s,%s " , srv_cn [ 0 ] , argv [ 0 ] , srv_dn ) ;
resolve_name ( servername , & server_ip , 0x20 ) ;
nt_status = cli_full_connection ( & cli , global_myname ( ) , servername ,
& server_ip , 0 ,
" IPC$ " , " IPC " ,
opt_user_name , opt_workgroup ,
opt_password ? opt_password : " " ,
CLI_FULL_CONNECTION_USE_KERBEROS ,
NULL ) ;
cli_nt_session_open ( cli , PI_SPOOLSS ) ;
get_remote_printer_publishing_data ( cli , mem_ctx , & mods , argv [ 0 ] ) ;
rc = ads_add_printer_entry ( ads , prt_dn , mem_ctx , & mods ) ;
2002-02-02 05:06:03 +03:00
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_publish_printer: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
d_printf ( " published printer \n " ) ;
return 0 ;
}
static int net_ads_printer_remove ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
2002-11-13 02:20:50 +03:00
const char * servername ;
char * prt_dn ;
2002-02-02 05:06:03 +03:00
void * res = NULL ;
if ( ! ( ads = ads_startup ( ) ) ) return - 1 ;
if ( argc < 1 )
return net_ads_printer_usage ( argc , argv ) ;
if ( argc > 1 )
servername = argv [ 1 ] ;
else
2002-11-13 02:20:50 +03:00
servername = global_myname ( ) ;
2002-02-02 05:06:03 +03:00
rc = ads_find_printer_on_server ( ads , & res , argv [ 0 ] , servername ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_find_printer_on_server: %s \n " , ads_errstr ( rc ) ) ;
ads_msgfree ( ads , res ) ;
return - 1 ;
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
d_printf ( " Printer '%s' not found \n " , argv [ 1 ] ) ;
ads_msgfree ( ads , res ) ;
return - 1 ;
}
prt_dn = ads_get_dn ( ads , res ) ;
ads_msgfree ( ads , res ) ;
rc = ads_del_dn ( ads , prt_dn ) ;
ads_memfree ( ads , prt_dn ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " ads_del_dn: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
return 0 ;
}
static int net_ads_printer ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " INFO " , net_ads_printer_info } ,
{ " PUBLISH " , net_ads_printer_publish } ,
{ " REMOVE " , net_ads_printer_remove } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_ads_printer_usage ) ;
}
2001-12-20 06:54:52 +03:00
static int net_ads_password ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
2003-01-03 11:28:12 +03:00
const char * auth_principal = opt_user_name ;
const char * auth_password = opt_password ;
2001-12-20 06:54:52 +03:00
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 */
2002-08-17 18:45:04 +04:00
if ( ! ( ads = ads_init ( realm , NULL , NULL ) ) ) return - 1 ;
2001-12-20 06:54:52 +03:00
asprintf ( & prompt , " Enter new password for %s: " , argv [ 0 ] ) ;
new_password = getpass ( prompt ) ;
2002-08-17 18:45:04 +04:00
ret = kerberos_set_password ( ads - > auth . kdc_server , auth_principal ,
2002-09-25 19:19:00 +04:00
auth_password , argv [ 0 ] , new_password , ads - > auth . time_offset ) ;
2001-12-20 06:54:52 +03:00
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 ;
char * host_principal ;
char * hostname ;
ADS_STATUS ret ;
2003-01-03 11:28:12 +03:00
char * user_name ;
2001-12-20 06:54:52 +03:00
2002-08-17 18:45:04 +04:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
return - 1 ;
}
2003-01-03 11:28:12 +03:00
asprintf ( & user_name , " %s$ " , global_myname ( ) ) ;
opt_user_name = user_name ;
2002-08-17 18:45:04 +04:00
opt_password = secrets_fetch_machine_password ( ) ;
if ( ! ( ads = ads_startup ( ) ) ) {
return - 1 ;
}
2001-12-20 06:54:52 +03:00
2002-11-13 02:20:50 +03:00
hostname = strdup ( global_myname ( ) ) ;
2001-12-20 06:54:52 +03:00
strlower ( hostname ) ;
2002-08-17 18:45:04 +04:00
asprintf ( & host_principal , " %s@%s " , hostname , ads - > config . realm ) ;
2001-12-20 06:54:52 +03:00
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 ;
}
2002-07-15 14:35:28 +04:00
/*
help for net ads search
*/
static int net_ads_search_usage ( int argc , const char * * argv )
{
d_printf (
" \n net ads search <expression> <attributes...> \n " \
" \n perform a raw LDAP search on a ADS server and dump the results \n " \
" The expression is a standard LDAP search expression, and the \n " \
" attributes are a list of LDAP fields to show in the results \n \n " \
" Example: net ads search '(objectCategory=group)' sAMAccountName \n \n "
) ;
net_common_flags_usage ( argc , argv ) ;
return - 1 ;
}
/*
general ADS search function . Useful in diagnosing problems in ADS
*/
static int net_ads_search ( int argc , const char * * argv )
{
ADS_STRUCT * ads ;
ADS_STATUS rc ;
const char * exp ;
const char * * attrs ;
void * res = NULL ;
if ( argc < 1 ) {
return net_ads_search_usage ( argc , argv ) ;
}
if ( ! ( ads = ads_startup ( ) ) ) {
return - 1 ;
}
exp = argv [ 0 ] ;
attrs = ( argv + 1 ) ;
2002-08-17 18:45:04 +04:00
rc = ads_do_search_all ( ads , ads - > config . bind_path ,
2002-07-15 14:35:28 +04:00
LDAP_SCOPE_SUBTREE ,
exp , attrs , & res ) ;
if ( ! ADS_ERR_OK ( rc ) ) {
d_printf ( " search failed: %s \n " , ads_errstr ( rc ) ) ;
return - 1 ;
}
d_printf ( " Got %d replies \n \n " , ads_count_replies ( ads , res ) ) ;
/* dump the results */
ads_dump ( ads , res ) ;
ads_msgfree ( ads , res ) ;
ads_destroy ( & ads ) ;
return 0 ;
}
2002-04-04 06:53:42 +04:00
int net_ads_help ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " USER " , net_ads_user_usage } ,
2002-07-15 14:35:28 +04:00
{ " GROUP " , net_ads_group_usage } ,
{ " PRINTER " , net_ads_printer_usage } ,
{ " SEARCH " , net_ads_search_usage } ,
2002-04-04 06:53:42 +04:00
#if 0
{ " INFO " , net_ads_info } ,
{ " JOIN " , net_ads_join } ,
{ " LEAVE " , net_ads_leave } ,
{ " STATUS " , net_ads_status } ,
{ " PASSWORD " , net_ads_password } ,
{ " CHOSTPASS " , net_ads_change_localhost_pass } ,
# endif
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_ads_usage ) ;
}
2001-12-20 06:54:52 +03:00
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 } ,
2002-08-17 18:45:04 +04:00
{ " TESTJOIN " , net_ads_testjoin } ,
2001-11-25 03:18:11 +03:00
{ " 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 } ,
2002-02-02 05:06:03 +03:00
{ " PRINTER " , net_ads_printer } ,
2002-07-15 14:35:28 +04:00
{ " SEARCH " , net_ads_search } ,
2002-08-17 18:45:04 +04:00
{ " WORKGROUP " , net_ads_workgroup } ,
2002-09-25 19:19:00 +04:00
{ " LOOKUP " , net_ads_lookup } ,
2002-04-04 06:53:42 +04:00
{ " HELP " , net_ads_help } ,
2001-11-25 03:18:11 +03:00
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_ads_usage ) ;
}
# else
2002-04-04 20:47:24 +04:00
static int net_ads_noads ( void )
2001-11-25 03:18:11 +03:00
{
d_printf ( " ADS support not compiled in \n " ) ;
return - 1 ;
}
2002-04-04 20:47:24 +04:00
int net_ads_usage ( int argc , const char * * argv )
{
return net_ads_noads ( ) ;
}
2002-04-04 07:14:25 +04:00
int net_ads_help ( int argc , const char * * argv )
{
2002-04-04 20:47:24 +04:00
return net_ads_noads ( ) ;
2002-04-04 07:14:25 +04:00
}
2002-03-16 04:30:09 +03:00
int net_ads_join ( int argc , const char * * argv )
2002-04-04 20:47:24 +04:00
{
return net_ads_noads ( ) ;
}
int net_ads_user ( int argc , const char * * argv )
{
return net_ads_noads ( ) ;
}
2002-07-15 14:35:28 +04:00
int net_ads_group ( int argc , const char * * argv )
{
return net_ads_noads ( ) ;
}
2002-04-04 20:47:24 +04:00
/* this one shouldn't display a message */
int net_ads_check ( void )
2002-03-16 04:30:09 +03:00
{
return - 1 ;
}
2001-11-25 03:18:11 +03:00
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