2007-09-18 01:04:10 +04:00
/*
Samba Unix / Linux SMB client library
2001-11-25 03:18:11 +03:00
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 )
2006-05-13 08:39:19 +04:00
Copyright ( C ) 2006 Gerald ( Jerry ) Carter ( jerry @ samba . org )
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-11-25 03:18:11 +03:00
( at your option ) any later version .
2007-09-18 01:04:10 +04:00
2001-11-25 03:18:11 +03:00
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 .
2007-09-18 01:04:10 +04:00
2001-11-25 03:18:11 +03:00
You should have received a copy of the GNU General Public License
2007-09-18 01:04:10 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2001-11-25 03:18:11 +03:00
*/
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2018-03-10 17:31:11 +03:00
# include "libsmb/namequery.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2008-10-20 21:21:10 +04:00
# include "librpc/gen_ndr/ndr_krb5pac.h"
2011-01-19 00:35:17 +03:00
# include "../librpc/gen_ndr/ndr_spoolss.h"
2009-07-27 19:37:22 +04:00
# include "nsswitch/libwbclient/wbclient.h"
2010-07-02 02:32:52 +04:00
# include "ads.h"
2010-05-18 21:40:31 +04:00
# include "libads/cldap.h"
2012-05-05 00:47:27 +04:00
# include "../lib/addns/dnsquery.h"
2010-07-01 01:38:57 +04:00
# include "../libds/common/flags.h"
2010-07-02 02:14:04 +04:00
# include "librpc/gen_ndr/libnet_join.h"
# include "libnet/libnet_join.h"
# include "smb_krb5.h"
2010-08-05 04:25:37 +04:00
# include "secrets.h"
2010-08-18 20:45:36 +04:00
# include "krb5_env.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2012-07-23 06:47:01 +04:00
# include "lib/param/loadparm.h"
2012-09-19 17:35:15 +04:00
# include "utils/net_dns.h"
2019-12-19 17:34:36 +03:00
# include "auth/kerberos/pac_utils.h"
2020-08-07 21:17:34 +03:00
# include "lib/util/string_wrappers.h"
2001-11-25 03:18:11 +03:00
2018-07-03 13:09:17 +03:00
# ifdef HAVE_JANSSON
# include <jansson.h>
# include "audit_logging.h" /* various JSON helpers */
# include "auth/common_auth.h"
# endif /* [HAVE_JANSSON] */
2001-11-25 03:18:11 +03:00
# ifdef HAVE_ADS
2006-07-17 15:04:47 +04:00
/* when we do not have sufficient input parameters to contact a remote domain
* we always fall back to our own realm - Guenther */
2008-05-10 01:22:12 +04:00
static const char * assume_own_realm ( struct net_context * c )
2006-07-17 15:04:47 +04:00
{
2008-05-10 01:22:12 +04:00
if ( ! c - > opt_host & & strequal ( lp_workgroup ( ) , c - > opt_target_workgroup ) ) {
2006-07-17 15:04:47 +04:00
return lp_realm ( ) ;
}
return NULL ;
}
2001-12-13 16:19:20 +03:00
2018-07-03 13:09:17 +03:00
# ifdef HAVE_JANSSON
/*
* note : JSON output deliberately bypasses gettext so as to provide the same
* output irrespective of the locale .
*/
static int output_json ( const struct json_object * jsobj )
{
TALLOC_CTX * ctx = NULL ;
char * json = NULL ;
if ( json_is_invalid ( jsobj ) ) {
return - 1 ;
}
ctx = talloc_new ( NULL ) ;
if ( ctx = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
return - 1 ;
}
json = json_to_string ( ctx , jsobj ) ;
if ( ! json ) {
d_fprintf ( stderr , _ ( " error encoding to JSON \n " ) ) ;
return - 1 ;
}
d_printf ( " %s \n " , json ) ;
TALLOC_FREE ( ctx ) ;
return 0 ;
}
static int net_ads_cldap_netlogon_json
( ADS_STRUCT * ads ,
const char * addr ,
const struct NETLOGON_SAM_LOGON_RESPONSE_EX * reply )
{
struct json_object jsobj = json_new_object ( ) ;
struct json_object flagsobj = json_new_object ( ) ;
char response_type [ 32 ] = { ' \0 ' } ;
int ret = 0 ;
if ( json_is_invalid ( & jsobj ) | | json_is_invalid ( & flagsobj ) ) {
d_fprintf ( stderr , _ ( " error setting up JSON value \n " ) ) ;
goto failure ;
}
switch ( reply - > command ) {
case LOGON_SAM_LOGON_USER_UNKNOWN_EX :
strncpy ( response_type ,
" LOGON_SAM_LOGON_USER_UNKNOWN_EX " ,
sizeof ( response_type ) ) ;
break ;
case LOGON_SAM_LOGON_RESPONSE_EX :
strncpy ( response_type , " LOGON_SAM_LOGON_RESPONSE_EX " ,
sizeof ( response_type ) ) ;
break ;
default :
snprintf ( response_type , sizeof ( response_type ) , " 0x%x " ,
reply - > command ) ;
break ;
}
ret = json_add_string ( & jsobj , " Information for Domain Controller " ,
addr ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Response Type " , response_type ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_guid ( & jsobj , " GUID " , & reply - > domain_uuid ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is a PDC " ,
reply - > server_type & NBT_SERVER_PDC ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is a GC of the forest " ,
reply - > server_type & NBT_SERVER_GC ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is an LDAP server " ,
reply - > server_type & NBT_SERVER_LDAP ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Supports DS " ,
reply - > server_type & NBT_SERVER_DS ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is running a KDC " ,
reply - > server_type & NBT_SERVER_KDC ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is running time services " ,
reply - > server_type & NBT_SERVER_TIMESERV ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is the closest DC " ,
reply - > server_type & NBT_SERVER_CLOSEST ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is writable " ,
reply - > server_type & NBT_SERVER_WRITABLE ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Has a hardware clock " ,
reply - > server_type & NBT_SERVER_GOOD_TIMESERV ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj ,
" Is a non-domain NC serviced by LDAP server " ,
reply - > server_type & NBT_SERVER_NDNC ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool
( & flagsobj , " Is NT6 DC that has some secrets " ,
reply - > server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6 ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool
( & flagsobj , " Is NT6 DC that has all secrets " ,
reply - > server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6 ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Runs Active Directory Web Services " ,
reply - > server_type & NBT_SERVER_ADS_WEB_SERVICE ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Runs on Windows 2012 or later " ,
reply - > server_type & NBT_SERVER_DS_8 ) ;
if ( ret ! = 0 ) {
goto failure ;
}
2023-05-24 00:48:19 +03:00
ret = json_add_bool ( & flagsobj , " Runs on Windows 2012R2 or later " ,
reply - > server_type & NBT_SERVER_DS_9 ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Runs on Windows 2016 or later " ,
reply - > server_type & NBT_SERVER_DS_10 ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Has a DNS name " ,
reply - > server_type & NBT_SERVER_HAS_DNS_NAME ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is a default NC " ,
reply - > server_type & NBT_SERVER_IS_DEFAULT_NC ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_bool ( & flagsobj , " Is the forest root " ,
reply - > server_type & NBT_SERVER_FOREST_ROOT ) ;
if ( ret ! = 0 ) {
goto failure ;
}
2018-07-03 13:09:17 +03:00
ret = json_add_string ( & jsobj , " Forest " , reply - > forest ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Domain " , reply - > dns_domain ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Domain Controller " , reply - > pdc_dns_name ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Pre-Win2k Domain " , reply - > domain_name ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Pre-Win2k Hostname " , reply - > pdc_name ) ;
if ( ret ! = 0 ) {
goto failure ;
}
if ( * reply - > user_name ) {
ret = json_add_string ( & jsobj , " User name " , reply - > user_name ) ;
if ( ret ! = 0 ) {
goto failure ;
}
}
ret = json_add_string ( & jsobj , " Server Site Name " , reply - > server_site ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Client Site Name " , reply - > client_site ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " NT Version " , reply - > nt_version ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " LMNT Token " , reply - > lmnt_token ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " LM20 Token " , reply - > lm20_token ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_object ( & jsobj , " Flags " , & flagsobj ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = output_json ( & jsobj ) ;
json_free ( & jsobj ) ; /* frees flagsobj recursively */
return ret ;
failure :
json_free ( & flagsobj ) ;
json_free ( & jsobj ) ;
return ret ;
}
# else /* [HAVE_JANSSON] */
static int net_ads_cldap_netlogon_json
2018-09-23 01:47:28 +03:00
( ADS_STRUCT * ads ,
const char * addr ,
const struct NETLOGON_SAM_LOGON_RESPONSE_EX * reply )
2018-07-03 13:09:17 +03:00
{
d_fprintf ( stderr , _ ( " JSON support not available \n " ) ) ;
return - 1 ;
}
# endif /* [HAVE_JANSSON] */
2006-05-12 19:17:35 +04:00
/*
do a cldap netlogon query
*/
2008-05-10 01:22:12 +04:00
static int net_ads_cldap_netlogon ( struct net_context * c , ADS_STRUCT * ads )
2006-05-12 19:17:35 +04:00
{
2007-10-25 01:16:54 +04:00
char addr [ INET6_ADDRSTRLEN ] ;
2008-09-24 00:21:52 +04:00
struct NETLOGON_SAM_LOGON_RESPONSE_EX reply ;
2006-05-12 19:17:35 +04:00
2007-10-25 01:16:54 +04:00
print_sockaddr ( addr , sizeof ( addr ) , & ads - > ldap . ss ) ;
2011-04-26 11:03:32 +04:00
if ( ! ads_cldap_netlogon_5 ( talloc_tos ( ) , & ads - > ldap . ss , ads - > server . realm , & reply ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " CLDAP query failed! \n " ) ) ;
2006-05-12 19:17:35 +04:00
return - 1 ;
}
2018-07-03 13:09:17 +03:00
if ( c - > opt_json ) {
return net_ads_cldap_netlogon_json ( ads , addr , & reply ) ;
}
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Information for Domain Controller: %s \n \n " ) ,
2007-10-25 01:16:54 +04:00
addr ) ;
2006-05-12 19:17:35 +04:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Response Type: " ) ) ;
2008-09-24 00:21:52 +04:00
switch ( reply . command ) {
2008-09-24 11:05:37 +04:00
case LOGON_SAM_LOGON_USER_UNKNOWN_EX :
d_printf ( " LOGON_SAM_LOGON_USER_UNKNOWN_EX \n " ) ;
2006-05-12 19:17:35 +04:00
break ;
2008-09-24 11:05:37 +04:00
case LOGON_SAM_LOGON_RESPONSE_EX :
d_printf ( " LOGON_SAM_LOGON_RESPONSE_EX \n " ) ;
2006-05-12 19:17:35 +04:00
break ;
default :
2008-09-24 00:21:52 +04:00
d_printf ( " 0x%x \n " , reply . command ) ;
2006-05-12 19:17:35 +04:00
break ;
}
2007-11-25 12:10:52 +03:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " GUID: %s \n " ) , GUID_string ( talloc_tos ( ) , & reply . domain_uuid ) ) ;
d_printf ( _ ( " Flags: \n "
" \t Is a PDC: %s \n "
" \t Is a GC of the forest: %s \n "
" \t Is an LDAP server: %s \n "
" \t Supports DS: %s \n "
" \t Is running a KDC: %s \n "
" \t Is running time services: %s \n "
" \t Is the closest DC: %s \n "
" \t Is writable: %s \n "
" \t Has a hardware clock: %s \n "
" \t Is a non-domain NC serviced by LDAP server: %s \n "
" \t Is NT6 DC that has some secrets: %s \n "
2014-10-23 16:04:35 +04:00
" \t Is NT6 DC that has all secrets: %s \n "
" \t Runs Active Directory Web Services: %s \n "
2023-05-24 00:48:19 +03:00
" \t Runs on Windows 2012 or later: %s \n "
" \t Runs on Windows 2012R2 or later: %s \n "
" \t Runs on Windows 2016 or later: %s \n "
" \t Has a DNS name: %s \n "
" \t Is a default NC: %s \n "
" \t Is the forest root: %s \n " ) ,
2009-07-30 01:28:01 +04:00
( reply . server_type & NBT_SERVER_PDC ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_GC ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_LDAP ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_DS ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_KDC ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_TIMESERV ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_CLOSEST ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_WRITABLE ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_GOOD_TIMESERV ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_NDNC ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6 ) ? _ ( " yes " ) : _ ( " no " ) ,
2014-10-23 16:04:35 +04:00
( reply . server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6 ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_ADS_WEB_SERVICE ) ? _ ( " yes " ) : _ ( " no " ) ,
2023-05-24 00:48:19 +03:00
( reply . server_type & NBT_SERVER_DS_8 ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_DS_9 ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_DS_10 ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_HAS_DNS_NAME ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_IS_DEFAULT_NC ) ? _ ( " yes " ) : _ ( " no " ) ,
( reply . server_type & NBT_SERVER_FOREST_ROOT ) ? _ ( " yes " ) : _ ( " no " ) ) ;
2009-07-30 01:28:01 +04:00
2018-08-20 16:10:31 +03:00
printf ( _ ( " Forest: %s \n " ) , reply . forest ) ;
printf ( _ ( " Domain: %s \n " ) , reply . dns_domain ) ;
printf ( _ ( " Domain Controller: %s \n " ) , reply . pdc_dns_name ) ;
2009-07-30 01:28:01 +04:00
2018-08-20 16:10:31 +03:00
printf ( _ ( " Pre-Win2k Domain: %s \n " ) , reply . domain_name ) ;
printf ( _ ( " Pre-Win2k Hostname: %s \n " ) , reply . pdc_name ) ;
2009-07-30 01:28:01 +04:00
2018-08-20 16:10:31 +03:00
if ( * reply . user_name ) printf ( _ ( " User name: %s \n " ) , reply . user_name ) ;
2009-07-30 01:28:01 +04:00
2018-08-20 16:10:31 +03:00
printf ( _ ( " Server Site Name: %s \n " ) , reply . server_site ) ;
printf ( _ ( " Client Site Name: %s \n " ) , reply . client_site ) ;
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " NT Version: %d \n " ) , reply . nt_version ) ;
d_printf ( _ ( " LMNT Token: %.2x \n " ) , reply . lmnt_token ) ;
d_printf ( _ ( " LM20 Token: %.2x \n " ) , reply . lm20_token ) ;
2006-05-12 19:17:35 +04:00
2006-05-13 05:29:04 +04:00
return 0 ;
2006-05-12 19:17:35 +04: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
*/
2008-05-10 01:22:12 +04:00
static int net_ads_lookup ( struct net_context * c , int argc , const char * * argv )
2002-09-25 19:19:00 +04:00
{
2022-05-25 18:02:14 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
int ret = - 1 ;
2002-09-25 19:19:00 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
" net ads lookup \n "
" %s " ,
_ ( " Usage: " ) ,
_ ( " Find the ADS DC using CLDAP lookup. \n " ) ) ;
2022-05-25 18:02:14 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-05-25 18:09:51 +03:00
status = ads_startup_nobind ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:02:14 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Didn't find the cldap server! \n " ) ) ;
2022-05-25 18:02:14 +03:00
goto out ;
2006-03-29 19:30:26 +04:00
}
2006-10-13 01:03:28 +04:00
2006-03-29 19:30:26 +04:00
if ( ! ads - > config . realm ) {
2022-06-13 18:44:02 +03:00
ads - > config . realm = talloc_strdup ( ads , c - > opt_target_workgroup ) ;
if ( ads - > config . realm = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
}
2007-07-16 15:08:00 +04:00
ads - > ldap . port = 389 ;
2002-09-25 19:19:00 +04:00
}
2009-02-10 00:25:59 +03:00
ret = net_ads_cldap_netlogon ( c , ads ) ;
2022-05-25 18:02:14 +03:00
out :
TALLOC_FREE ( tmp_ctx ) ;
2009-02-10 00:25:59 +03:00
return ret ;
2002-09-25 19:19:00 +04:00
}
2018-07-02 17:21:59 +03:00
# ifdef HAVE_JANSSON
static int net_ads_info_json ( ADS_STRUCT * ads )
{
int ret = 0 ;
char addr [ INET6_ADDRSTRLEN ] ;
time_t pass_time ;
struct json_object jsobj = json_new_object ( ) ;
if ( json_is_invalid ( & jsobj ) ) {
d_fprintf ( stderr , _ ( " error setting up JSON value \n " ) ) ;
goto failure ;
}
pass_time = secrets_fetch_pass_last_set_time ( ads - > server . workgroup ) ;
print_sockaddr ( addr , sizeof ( addr ) , & ads - > ldap . ss ) ;
ret = json_add_string ( & jsobj , " LDAP server " , addr ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " LDAP server name " ,
ads - > config . ldap_server_name ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Realm " , ads - > config . realm ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " Bind Path " , ads - > config . bind_path ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " LDAP port " , ads - > ldap . port ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " Server time " , ads - > config . current_time ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_string ( & jsobj , " KDC server " , ads - > auth . kdc_server ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " Server time offset " ,
ads - > auth . time_offset ) ;
if ( ret ! = 0 ) {
goto failure ;
}
ret = json_add_int ( & jsobj , " Last machine account password change " ,
pass_time ) ;
if ( ret ! = 0 ) {
goto failure ;
}
2018-07-03 13:09:17 +03:00
ret = output_json ( & jsobj ) ;
2018-07-02 17:21:59 +03:00
failure :
2018-07-03 13:09:17 +03:00
json_free ( & jsobj ) ;
2018-07-02 17:21:59 +03:00
return ret ;
}
# else /* [HAVE_JANSSON] */
2018-09-23 01:47:28 +03:00
static int net_ads_info_json ( ADS_STRUCT * ads )
2018-07-02 17:21:59 +03:00
{
d_fprintf ( stderr , _ ( " JSON support not available \n " ) ) ;
return - 1 ;
}
# endif /* [HAVE_JANSSON] */
2002-09-25 19:19:00 +04:00
2008-05-10 01:22:12 +04:00
static int net_ads_info ( struct net_context * c , int argc , const char * * argv )
2001-12-13 16:19:20 +03:00
{
2022-05-25 18:04:58 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2007-10-25 01:16:54 +04:00
char addr [ INET6_ADDRSTRLEN ] ;
2015-07-31 01:52:08 +03:00
time_t pass_time ;
2022-05-25 18:04:58 +03:00
int ret = - 1 ;
2001-12-13 16:19:20 +03:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
" net ads info \n "
" %s " ,
_ ( " Usage: " ) ,
_ ( " Display information about an Active Directory "
2009-07-30 01:28:01 +04:00
" server. \n " ) ) ;
2022-05-25 18:04:58 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-05-25 18:09:51 +03:00
status = ads_startup_nobind ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:04:58 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Didn't find the ldap server! \n " ) ) ;
2022-05-25 18:04:58 +03:00
goto out ;
2002-08-17 18:45:04 +04:00
}
if ( ! ads | | ! ads - > config . realm ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Didn't find the ldap server! \n " ) ) ;
2022-05-25 18:04:58 +03:00
goto out ;
2001-12-13 16:19:20 +03:00
}
2006-05-12 19:17:35 +04:00
/* Try to set the server's current time since we didn't do a full
TCP LDAP session initially */
if ( ! ADS_ERR_OK ( ads_current_time ( ads ) ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Failed to get server's current time! \n " ) ) ;
2006-05-12 19:17:35 +04:00
}
2018-07-02 17:21:59 +03:00
if ( c - > opt_json ) {
2022-05-25 18:04:58 +03:00
ret = net_ads_info_json ( ads ) ;
goto out ;
2018-07-02 17:21:59 +03:00
}
2015-07-31 01:52:08 +03:00
pass_time = secrets_fetch_pass_last_set_time ( ads - > server . workgroup ) ;
2007-10-25 01:16:54 +04:00
print_sockaddr ( addr , sizeof ( addr ) , & ads - > ldap . ss ) ;
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " LDAP server: %s \n " ) , addr ) ;
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 ) ;
d_printf ( _ ( " LDAP port: %d \n " ) , ads - > ldap . port ) ;
d_printf ( _ ( " Server time: %s \n " ) ,
2022-05-25 18:04:58 +03:00
http_timestring ( tmp_ctx , ads - > config . current_time ) ) ;
2001-12-13 16:19:20 +03:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " KDC server: %s \n " ) , ads - > auth . kdc_server ) ;
d_printf ( _ ( " Server time offset: %d \n " ) , ads - > auth . time_offset ) ;
2003-05-04 06:48:11 +04:00
2015-07-31 01:52:08 +03:00
d_printf ( _ ( " Last machine account password change: %s \n " ) ,
2022-05-25 18:04:58 +03:00
http_timestring ( tmp_ctx , pass_time ) ) ;
2015-07-31 01:52:08 +03:00
2022-05-25 18:04:58 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2001-12-13 16:19:20 +03:00
}
2022-05-26 15:43:25 +03:00
static ADS_STATUS ads_startup_int ( struct net_context * c ,
bool only_own_domain ,
uint32_t auth_flags ,
TALLOC_CTX * mem_ctx ,
ADS_STRUCT * * ads_ret )
2001-11-25 03:18:11 +03:00
{
2006-10-13 01:03:28 +04:00
ADS_STRUCT * ads = NULL ;
2001-12-19 15:21:12 +03:00
ADS_STATUS status ;
2008-05-12 13:53:23 +04:00
bool need_password = false ;
bool second_time = false ;
2003-09-04 23:45:04 +04:00
char * cp ;
2006-07-17 15:04:47 +04:00
const char * realm = NULL ;
2008-05-12 13:53:23 +04:00
bool tried_closest_dc = false ;
2021-12-10 18:08:04 +03:00
enum credentials_use_kerberos krb5_state =
CRED_USE_KERBEROS_DISABLED ;
2006-10-13 01:03:28 +04:00
2007-09-18 01:04:10 +04:00
/* lp_realm() should be handled by a command line param,
2003-09-04 23:45:04 +04:00
However , the join requires that realm be set in smb . conf
and compares our realm with the remote server ' s so this is
ok until someone needs more flexibility */
2006-07-17 15:04:47 +04:00
2006-10-13 01:03:28 +04:00
* ads_ret = NULL ;
retry_connect :
2006-07-17 15:04:47 +04:00
if ( only_own_domain ) {
realm = lp_realm ( ) ;
2006-10-13 01:03:28 +04:00
} else {
2008-05-10 01:22:12 +04:00
realm = assume_own_realm ( c ) ;
2006-07-17 15:04:47 +04:00
}
2006-10-13 01:03:28 +04:00
2022-05-26 18:28:34 +03:00
ads = ads_init ( mem_ctx ,
realm ,
c - > opt_target_workgroup ,
c - > opt_host ,
ADS_SASL_PLAIN ) ;
if ( ads = = NULL ) {
return ADS_ERROR_NT ( NT_STATUS_NO_MEMORY ) ;
}
2001-11-25 04:06:56 +03:00
2009-07-05 11:21:07 +04:00
if ( ! c - > opt_user_name ) {
c - > opt_user_name = " administrator " ;
}
if ( c - > opt_user_specified ) {
need_password = true ;
}
2002-01-26 01:07:46 +03:00
retry :
2009-07-05 11:21:07 +04:00
if ( ! c - > opt_password & & need_password & & ! c - > opt_machine_pass ) {
c - > opt_password = net_prompt_pass ( c , c - > opt_user_name ) ;
if ( ! c - > opt_password ) {
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ads ) ;
2009-07-05 11:21:07 +04:00
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
2001-12-08 14:18:56 +03:00
}
2002-01-26 01:07:46 +03:00
2009-07-05 11:21:07 +04:00
if ( c - > opt_password ) {
2003-03-18 01:33:34 +03:00
use_in_memory_ccache ( ) ;
2016-08-17 12:58:02 +03:00
ADS_TALLOC_CONST_FREE ( ads - > auth . password ) ;
2022-06-13 14:56:10 +03:00
ads - > auth . password = talloc_strdup ( ads , c - > opt_password ) ;
if ( ads - > auth . password = = NULL ) {
TALLOC_FREE ( ads ) ;
return ADS_ERROR_NT ( NT_STATUS_NO_MEMORY ) ;
}
2003-03-18 01:33:34 +03:00
}
2002-02-17 01:11:49 +03:00
2016-08-17 12:58:02 +03:00
ADS_TALLOC_CONST_FREE ( ads - > auth . user_name ) ;
2022-06-13 17:53:32 +03:00
ads - > auth . user_name = talloc_strdup ( ads , c - > opt_user_name ) ;
if ( ads - > auth . user_name = = NULL ) {
TALLOC_FREE ( ads ) ;
return ADS_ERROR_NT ( NT_STATUS_NO_MEMORY ) ;
}
2003-05-04 06:48:11 +04:00
2021-12-10 18:08:04 +03:00
ads - > auth . flags | = auth_flags ;
/* The ADS code will handle FIPS mode */
krb5_state = cli_credentials_get_kerberos_state ( c - > creds ) ;
switch ( krb5_state ) {
case CRED_USE_KERBEROS_REQUIRED :
ads - > auth . flags & = ~ ADS_AUTH_DISABLE_KERBEROS ;
ads - > auth . flags & = ~ ADS_AUTH_ALLOW_NTLMSSP ;
break ;
case CRED_USE_KERBEROS_DESIRED :
ads - > auth . flags & = ~ ADS_AUTH_DISABLE_KERBEROS ;
ads - > auth . flags | = ADS_AUTH_ALLOW_NTLMSSP ;
break ;
case CRED_USE_KERBEROS_DISABLED :
ads - > auth . flags | = ADS_AUTH_DISABLE_KERBEROS ;
ads - > auth . flags | = ADS_AUTH_ALLOW_NTLMSSP ;
break ;
}
2003-05-04 06:48:11 +04:00
/*
2007-09-18 01:04:10 +04:00
* If the username is of the form " name@realm " ,
2003-05-04 06:48:11 +04:00
* extract the realm and convert to upper case .
* This is only used to establish the connection .
*/
2006-10-13 01:03:28 +04:00
if ( ( cp = strchr_m ( ads - > auth . user_name , ' @ ' ) ) ! = 0 ) {
* cp + + = ' \0 ' ;
2016-08-17 12:58:02 +03:00
ADS_TALLOC_CONST_FREE ( ads - > auth . realm ) ;
2022-06-13 13:38:24 +03:00
ads - > auth . realm = talloc_asprintf_strupper_m ( ads , " %s " , cp ) ;
if ( ads - > auth . realm = = NULL ) {
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ads ) ;
2012-08-09 02:35:28 +04:00
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
2023-03-02 16:46:25 +03:00
} else if ( ads - > auth . realm = = NULL ) {
const char * c_realm = cli_credentials_get_realm ( c - > creds ) ;
2023-06-02 16:27:55 +03:00
if ( c_realm ! = NULL ) {
ads - > auth . realm = talloc_strdup ( ads , c_realm ) ;
if ( ads - > auth . realm = = NULL ) {
TALLOC_FREE ( ads ) ;
return ADS_ERROR ( LDAP_NO_MEMORY ) ;
}
2023-03-02 16:46:25 +03:00
}
}
2001-12-08 14:18:56 +03:00
2006-10-13 01:03:28 +04:00
status = ads_connect ( ads ) ;
2003-05-04 06:48:11 +04:00
2001-12-19 15:21:12 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2006-10-25 16:10:48 +04:00
2007-09-18 01:04:10 +04:00
if ( NT_STATUS_EQUAL ( ads_ntstatus ( status ) ,
2006-10-25 16:10:48 +04:00
NT_STATUS_NO_LOGON_SERVERS ) ) {
DEBUG ( 0 , ( " ads_connect: %s \n " , ads_errstr ( status ) ) ) ;
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ads ) ;
2006-10-25 16:10:48 +04:00
return status ;
}
2007-09-18 01:04:10 +04:00
2007-01-17 21:25:35 +03:00
if ( ! need_password & & ! second_time & & ! ( auth_flags & ADS_AUTH_NO_BIND ) ) {
2008-05-12 13:53:23 +04:00
need_password = true ;
second_time = true ;
2002-01-26 01:07:46 +03:00
goto retry ;
} else {
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ads ) ;
2006-10-13 01:03:28 +04:00
return status ;
}
}
/* when contacting our own domain, make sure we use the closest DC.
* This is done by reconnecting to ADS because only the first call to
* ads_connect will give us our own sitename */
2008-05-10 01:22:12 +04:00
if ( ( only_own_domain | | ! c - > opt_host ) & & ! tried_closest_dc ) {
2006-10-13 01:03:28 +04:00
2008-05-12 13:53:23 +04:00
tried_closest_dc = true ; /* avoid loop */
2006-10-13 01:03:28 +04:00
2008-10-22 12:36:21 +04:00
if ( ! ads_closest_dc ( ads ) ) {
2006-10-13 01:03:28 +04:00
namecache_delete ( ads - > server . realm , 0x1C ) ;
namecache_delete ( ads - > server . workgroup , 0x1C ) ;
2022-05-26 18:28:34 +03:00
TALLOC_FREE ( ads ) ;
2006-10-13 01:03:28 +04:00
goto retry_connect ;
2002-01-26 01:07:46 +03:00
}
2001-11-25 04:31:07 +03:00
}
2006-10-13 01:03:28 +04:00
2022-05-26 18:28:34 +03:00
* ads_ret = talloc_move ( mem_ctx , & ads ) ;
2006-08-17 16:44:59 +04:00
return status ;
2001-11-25 04:31:07 +03:00
}
2022-05-26 15:41:24 +03:00
ADS_STATUS ads_startup ( struct net_context * c ,
bool only_own_domain ,
TALLOC_CTX * mem_ctx ,
ADS_STRUCT * * ads )
2006-10-13 01:03:28 +04:00
{
2022-05-26 15:43:25 +03:00
return ads_startup_int ( c , only_own_domain , 0 , mem_ctx , ads ) ;
2006-10-13 01:03:28 +04:00
}
2022-05-25 18:09:51 +03:00
ADS_STATUS ads_startup_nobind ( struct net_context * c ,
bool only_own_domain ,
TALLOC_CTX * mem_ctx ,
ADS_STRUCT * * ads )
2006-10-13 01:03:28 +04:00
{
2022-05-26 15:43:25 +03:00
return ads_startup_int ( c ,
only_own_domain ,
ADS_AUTH_NO_BIND ,
mem_ctx ,
ads ) ;
2006-10-13 01:03:28 +04:00
}
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 .
*/
2022-05-26 16:13:02 +03:00
static int net_ads_check_int ( struct net_context * c ,
const char * realm ,
const char * workgroup ,
const char * host )
2002-04-04 20:47:24 +04:00
{
2022-05-26 16:13:02 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2002-04-04 20:47:24 +04:00
ADS_STRUCT * ads ;
2006-05-12 19:17:35 +04:00
ADS_STATUS status ;
2022-05-26 16:13:02 +03:00
int ret = - 1 ;
2002-04-04 20:47:24 +04:00
2022-05-26 18:28:34 +03:00
ads = ads_init ( tmp_ctx , realm , workgroup , host , ADS_SASL_PLAIN ) ;
2022-05-26 16:13:02 +03:00
if ( ads = = NULL ) {
goto out ;
2006-05-12 19:17:35 +04:00
}
ads - > auth . flags | = ADS_AUTH_NO_BIND ;
status = ads_connect ( ads ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2022-05-26 16:13:02 +03:00
goto out ;
2006-05-12 19:17:35 +04:00
}
2022-05-26 16:13:02 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-04-04 20:47:24 +04:00
}
2008-05-10 01:22:12 +04:00
int net_ads_check_our_domain ( struct net_context * c )
2006-07-17 15:04:47 +04:00
{
2022-05-26 16:13:02 +03:00
return net_ads_check_int ( c , lp_realm ( ) , lp_workgroup ( ) , NULL ) ;
2006-07-17 15:04:47 +04:00
}
2008-05-10 01:22:12 +04:00
int net_ads_check ( struct net_context * c )
2006-07-17 15:04:47 +04:00
{
2022-05-26 16:13:02 +03:00
return net_ads_check_int ( c , NULL , c - > opt_workgroup , c - > opt_host ) ;
2006-07-17 15:04:47 +04:00
}
2007-09-18 01:04:10 +04:00
/*
2002-08-17 18:45:04 +04:00
determine the netbios workgroup name for a domain
*/
2008-05-10 01:22:12 +04:00
static int net_ads_workgroup ( struct net_context * c , int argc , const char * * argv )
2002-08-17 18:45:04 +04:00
{
2022-05-25 18:07:42 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2008-09-24 00:21:52 +04:00
struct NETLOGON_SAM_LOGON_RESPONSE_EX reply ;
2022-05-25 18:07:42 +03:00
bool ok = false ;
int ret = - 1 ;
2002-08-17 18:45:04 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads workgroup \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Print the workgroup name " ) ) ;
2022-05-25 18:07:42 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-05-25 18:09:51 +03:00
status = ads_startup_nobind ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:07:42 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Didn't find the cldap server! \n " ) ) ;
2022-05-25 18:07:42 +03:00
goto out ;
2006-05-12 19:17:35 +04:00
}
2007-09-18 01:04:10 +04:00
2006-05-12 19:17:35 +04:00
if ( ! ads - > config . realm ) {
2022-06-13 18:44:02 +03:00
ads - > config . realm = talloc_strdup ( ads , c - > opt_target_workgroup ) ;
if ( ads - > config . realm = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
}
2007-07-16 15:08:00 +04:00
ads - > ldap . port = 389 ;
2006-05-12 19:17:35 +04:00
}
2007-09-18 01:04:10 +04:00
2022-05-25 18:07:42 +03:00
ok = ads_cldap_netlogon_5 ( tmp_ctx ,
& ads - > ldap . ss , ads - > server . realm , & reply ) ;
if ( ! ok ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " CLDAP query failed! \n " ) ) ;
2022-05-25 18:07:42 +03:00
goto out ;
2002-08-17 18:45:04 +04:00
}
2002-04-04 20:47:24 +04:00
2010-04-27 23:10:20 +04:00
d_printf ( _ ( " Workgroup: %s \n " ) , reply . domain_name ) ;
2002-08-17 18:45:04 +04:00
2022-05-25 18:07:42 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2007-09-18 01:04:10 +04:00
2022-05-25 18:07:42 +03:00
return ret ;
2002-08-17 18:45:04 +04:00
}
2007-10-19 04:40:25 +04:00
static bool usergrp_display ( ADS_STRUCT * ads , 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 */
2005-05-17 02:54:46 +04:00
if ( disp_fields [ 0 ] ) {
if ( ! strchr_m ( disp_fields [ 0 ] , ' $ ' ) ) {
if ( disp_fields [ 1 ] )
2007-09-18 01:04:10 +04:00
d_printf ( " %-21.21s %s \n " ,
2005-05-17 02:54:46 +04:00
disp_fields [ 0 ] , disp_fields [ 1 ] ) ;
else
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 ] ) ;
2008-05-12 13:53:23 +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 */
2008-05-12 13:53:23 +04:00
return true ;
2011-05-13 22:21:30 +04:00
if ( strcasecmp_m ( field , " sAMAccountName " ) = = 0 ) {
2004-12-07 21:25:53 +03:00
disp_fields [ 0 ] = SMB_STRDUP ( ( char * ) values [ 0 ] ) ;
2002-03-30 00:09:44 +03:00
}
2011-05-13 22:21:30 +04:00
if ( strcasecmp_m ( field , " description " ) = = 0 )
2004-12-07 21:25:53 +03:00
disp_fields [ 1 ] = SMB_STRDUP ( ( char * ) values [ 0 ] ) ;
2008-05-12 13:53:23 +04:00
return true ;
2002-03-30 00:09:44 +03:00
}
2008-05-10 01:22:12 +04:00
static int net_ads_user_usage ( struct net_context * c , int argc , const char * * argv )
2002-04-04 06:53:42 +04:00
{
2008-05-13 14:51:09 +04:00
return net_user_usage ( c , argc , argv ) ;
2007-09-18 01:04:10 +04:00
}
2002-04-04 06:53:42 +04:00
2008-05-10 01:22:12 +04:00
static int ads_user_add ( struct net_context * c , int argc , const char * * argv )
2002-04-04 06:53:42 +04:00
{
2022-05-25 18:18:08 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
2002-04-04 06:53:42 +04:00
ADS_STATUS status ;
2002-07-15 14:35:28 +04:00
char * upn , * userdn ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2002-04-04 06:53:42 +04:00
int rc = - 1 ;
2006-11-01 14:19:33 +03:00
char * ou_str = NULL ;
2002-04-04 06:53:42 +04:00
2022-05-25 18:18:08 +03:00
if ( argc < 1 | | c - > display_usage ) {
TALLOC_FREE ( tmp_ctx ) ;
2008-05-20 15:35:04 +04:00
return net_ads_user_usage ( c , argc , argv ) ;
2022-05-25 18:18:08 +03:00
}
2007-09-18 01:04:10 +04:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:18:08 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto done ;
2004-06-23 04:20:31 +04:00
}
2002-04-04 06:53:42 +04:00
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ads_user_add: %s \n " ) , ads_errstr ( status ) ) ;
2002-04-04 06:53:42 +04:00
goto done ;
}
2007-09-18 01:04:10 +04:00
2002-04-04 06:53:42 +04:00
if ( ads_count_replies ( ads , res ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ads_user_add: User %s already exists \n " ) ,
argv [ 0 ] ) ;
2002-04-04 06:53:42 +04:00
goto done ;
}
2008-05-10 01:22:12 +04:00
if ( c - > opt_container ) {
ou_str = SMB_STRDUP ( c - > opt_container ) ;
2006-11-01 14:19:33 +03:00
} else {
2010-07-01 01:09:05 +04:00
ou_str = ads_default_ou_string ( ads , DS_GUID_USERS_CONTAINER ) ;
2004-10-06 20:21:35 +04:00
}
2008-05-10 01:22:12 +04:00
status = ads_add_user_acct ( ads , argv [ 0 ] , ou_str , c - > opt_comment ) ;
2002-07-15 14:35:28 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Could not add user %s: %s \n " ) , argv [ 0 ] ,
2002-07-15 14:35:28 +04:00
ads_errstr ( status ) ) ;
goto done ;
}
/* if no password is to be set, we're done */
2007-09-18 01:04:10 +04:00
if ( argc = = 1 ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " User %s added \n " ) , argv [ 0 ] ) ;
2002-07-15 14:35:28 +04:00
rc = 0 ;
goto done ;
}
/* try setting the password */
2022-05-25 18:18:08 +03:00
upn = talloc_asprintf ( tmp_ctx ,
" %s@%s " ,
argv [ 0 ] ,
ads - > config . realm ) ;
if ( upn = = NULL ) {
2009-01-01 05:06:57 +03:00
goto done ;
}
2022-05-25 18:18:08 +03:00
2007-09-18 01:04:10 +04:00
status = ads_krb5_set_password ( ads - > auth . kdc_server , upn , argv [ 1 ] ,
2003-05-30 23:51:09 +04:00
ads - > auth . time_offset ) ;
2002-04-04 06:53:42 +04:00
if ( ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " User %s added \n " ) , argv [ 0 ] ) ;
2002-04-04 06:53:42 +04:00
rc = 0 ;
2002-07-15 14:35:28 +04:00
goto done ;
}
2022-05-25 18:18:08 +03:00
TALLOC_FREE ( upn ) ;
2002-07-15 14:35:28 +04:00
/* password didn't set, delete account */
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Could not add user %s. "
" Error setting password %s \n " ) ,
2002-07-15 14:35:28 +04:00
argv [ 0 ] , ads_errstr ( status ) ) ;
2022-05-25 18:18:08 +03:00
2002-07-15 14:35:28 +04:00
ads_msgfree ( ads , res ) ;
2022-05-25 18:18:08 +03:00
res = NULL ;
2002-07-15 14:35:28 +04:00
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ADS_ERR_OK ( status ) ) {
2022-05-25 18:18:08 +03:00
userdn = ads_get_dn ( ads , tmp_ctx , res ) ;
2002-07-15 14:35:28 +04:00
ads_del_dn ( ads , userdn ) ;
2009-03-18 09:35:03 +03:00
TALLOC_FREE ( userdn ) ;
2002-04-04 06:53:42 +04:00
}
done :
2022-05-25 18:18:08 +03:00
ads_msgfree ( ads , res ) ;
2006-11-01 14:19:33 +03:00
SAFE_FREE ( ou_str ) ;
2022-05-25 18:18:08 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2002-04-04 06:53:42 +04:00
return rc ;
}
2008-05-10 01:22:12 +04:00
static int ads_user_info ( struct net_context * c , int argc , const char * * argv )
2001-11-25 04:31:07 +03:00
{
2022-05-25 18:27:41 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2009-07-27 19:37:22 +04:00
ADS_STRUCT * ads = NULL ;
2022-05-25 18:27:41 +03:00
ADS_STATUS status ;
2009-07-27 19:37:22 +04:00
LDAPMessage * res = NULL ;
2022-05-25 18:27:41 +03:00
int ret = - 1 ;
2009-07-27 19:37:22 +04:00
wbcErr wbc_status ;
const char * attrs [ ] = { " memberOf " , " primaryGroupID " , NULL } ;
2022-05-25 18:27:41 +03:00
char * searchstring = NULL ;
char * * grouplist = NULL ;
char * primary_group = NULL ;
char * escaped_user = NULL ;
2010-05-21 05:25:01 +04:00
struct dom_sid primary_group_sid ;
2009-07-27 19:37:22 +04:00
uint32_t group_rid ;
2010-05-25 14:43:00 +04:00
enum wbcSidType type ;
2002-04-04 06:53:42 +04:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-25 18:27:41 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_user_usage ( c , argc , argv ) ;
2004-06-23 04:20:31 +04:00
}
2005-05-19 14:52:36 +04:00
2022-05-25 18:27:41 +03:00
escaped_user = escape_ldap_string ( tmp_ctx , argv [ 0 ] ) ;
2003-02-01 10:59:29 +03:00
if ( ! escaped_user ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr ,
_ ( " ads_user_info: failed to escape user %s \n " ) ,
argv [ 0 ] ) ;
2022-05-25 18:27:41 +03:00
goto out ;
2006-03-09 23:51:22 +03:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:27:41 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2003-02-01 10:59:29 +03:00
}
2022-05-25 18:27:41 +03:00
searchstring = talloc_asprintf ( tmp_ctx ,
" (sAMAccountName=%s) " ,
escaped_user ) ;
if ( searchstring = = NULL ) {
goto out ;
2009-01-01 05:06:57 +03:00
}
2001-11-25 04:31:07 +03:00
2022-05-25 18:27:41 +03:00
status = ads_search ( ads , & res , searchstring , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_search: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2002-03-20 01:16:19 +03:00
}
2007-09-18 01:04:10 +04:00
2009-07-27 19:37:22 +04:00
if ( ! ads_pull_uint32 ( ads , res , " primaryGroupID " , & group_rid ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ads_pull_uint32 failed \n " ) ) ;
2022-05-25 18:27:41 +03:00
goto out ;
2009-07-27 19:37:22 +04:00
}
2022-05-25 18:27:41 +03:00
status = ads_domain_sid ( ads , & primary_group_sid ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_domain_sid: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2009-07-27 19:37:22 +04:00
}
sid_append_rid ( & primary_group_sid , group_rid ) ;
wbc_status = wbcLookupSid ( ( struct wbcDomainSid * ) & primary_group_sid ,
NULL , /* don't look up domain */
& primary_group ,
2010-05-25 14:43:00 +04:00
& type ) ;
2009-07-27 19:37:22 +04:00
if ( ! WBC_ERROR_IS_OK ( wbc_status ) ) {
d_fprintf ( stderr , " wbcLookupSid: %s \n " ,
wbcErrorString ( wbc_status ) ) ;
2022-05-25 18:27:41 +03:00
goto out ;
2009-07-27 19:37:22 +04:00
}
d_printf ( " %s \n " , primary_group ) ;
wbcFreeMemory ( primary_group ) ;
2007-07-16 15:08:00 +04:00
grouplist = ldap_get_values ( ( LDAP * ) ads - > ldap . ld ,
2006-07-11 22:01:26 +04:00
( LDAPMessage * ) res , " memberOf " ) ;
2002-04-04 06:53:42 +04:00
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 ) ;
}
2007-09-18 01:04:10 +04:00
2022-05-25 18:27:41 +03:00
ret = 0 ;
out :
2023-11-15 16:26:09 +03:00
TALLOC_FREE ( escaped_user ) ;
TALLOC_FREE ( searchstring ) ;
2022-05-25 18:27:41 +03:00
ads_msgfree ( ads , res ) ;
TALLOC_FREE ( tmp_ctx ) ;
2009-07-27 19:37:22 +04:00
return ret ;
2001-11-25 04:31:07 +03:00
}
2008-05-10 01:22:12 +04:00
static int ads_user_delete ( struct net_context * c , int argc , const char * * argv )
2002-04-04 06:53:42 +04:00
{
2022-05-25 18:33:02 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2006-11-01 13:38:54 +03:00
LDAPMessage * res = NULL ;
2022-05-25 18:33:02 +03:00
char * userdn = NULL ;
int ret = - 1 ;
2002-04-04 06:53:42 +04:00
2004-06-23 04:20:31 +04:00
if ( argc < 1 ) {
2022-05-25 18:33:02 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_user_usage ( c , argc , argv ) ;
2004-06-23 04:20:31 +04:00
}
2007-09-18 01:04:10 +04:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:33:02 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2002-04-04 06:53:42 +04:00
2022-05-25 18:33:02 +03:00
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) | | ads_count_replies ( ads , res ) ! = 1 ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " User %s does not exist. \n " ) , argv [ 0 ] ) ;
2022-05-25 18:33:02 +03:00
goto out ;
2002-04-04 06:53:42 +04:00
}
2022-05-25 18:33:02 +03:00
userdn = ads_get_dn ( ads , tmp_ctx , res ) ;
if ( userdn = = NULL ) {
goto out ;
2002-04-04 06:53:42 +04:00
}
2022-05-25 18:33:02 +03:00
status = ads_del_dn ( ads , userdn ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " Error deleting user %s: %s \n " ) , argv [ 0 ] ,
ads_errstr ( status ) ) ;
goto out ;
}
d_printf ( _ ( " User %s deleted \n " ) , argv [ 0 ] ) ;
ret = 0 ;
out :
ads_msgfree ( ads , res ) ;
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-04-04 06:53:42 +04:00
}
2008-05-10 01:22:12 +04:00
int net_ads_user ( struct net_context * c , int argc , const char * * argv )
2002-04-04 06:53:42 +04:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" add " ,
ads_user_add ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Add an AD user " ) ,
N_ ( " net ads user add \n "
" Add an AD user " )
2008-05-20 15:35:04 +04:00
} ,
{
" info " ,
ads_user_info ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Display information about an AD user " ) ,
N_ ( " net ads user info \n "
" Display information about an AD user " )
2008-05-20 15:35:04 +04:00
} ,
{
" delete " ,
ads_user_delete ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Delete an AD user " ) ,
N_ ( " net ads user delete \n "
" Delete an AD user " )
2008-05-20 15:35:04 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2002-04-04 06:53:42 +04:00
} ;
2022-05-25 18:41:50 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2002-04-04 06:53:42 +04:00
const char * shortattrs [ ] = { " sAMAccountName " , NULL } ;
const char * longattrs [ ] = { " sAMAccountName " , " description " , NULL } ;
char * disp_fields [ 2 ] = { NULL , NULL } ;
2022-05-25 18:41:50 +03:00
int ret = - 1 ;
2007-09-18 01:04:10 +04:00
2022-05-25 18:41:50 +03:00
if ( argc > 0 ) {
TALLOC_FREE ( tmp_ctx ) ;
return net_run_function ( c , argc , argv , " net ads user " , func ) ;
}
2008-05-20 15:35:04 +04:00
2022-05-25 18:41:50 +03:00
if ( c - > display_usage ) {
d_printf ( " %s \n "
" net ads user \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " List AD users " ) ) ;
net_display_usage_from_functable ( func ) ;
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2022-05-25 18:41:50 +03:00
}
2002-04-04 06:53:42 +04:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:41:50 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
}
if ( c - > opt_long_list_entries )
d_printf ( _ ( " \n User name Comment "
" \n ----------------------------- \n " ) ) ;
2002-04-04 06:53:42 +04:00
2022-05-25 18:41:50 +03:00
status = ads_do_search_all_fn ( ads ,
ads - > config . bind_path ,
LDAP_SCOPE_SUBTREE ,
" (objectCategory=user) " ,
c - > opt_long_list_entries ?
longattrs : shortattrs ,
usergrp_display ,
disp_fields ) ;
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2002-04-04 06:53:42 +04:00
}
2022-05-25 18:41:50 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-04-04 06:53:42 +04:00
}
2008-05-10 01:22:12 +04:00
static int net_ads_group_usage ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
2008-05-13 15:44:28 +04:00
return net_group_usage ( c , argc , argv ) ;
2007-09-18 01:04:10 +04:00
}
2002-07-15 14:35:28 +04:00
2008-05-10 01:22:12 +04:00
static int ads_group_add ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
2022-05-25 18:57:34 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
2002-07-15 14:35:28 +04:00
ADS_STATUS status ;
2022-05-25 18:57:34 +03:00
LDAPMessage * res = NULL ;
int ret = - 1 ;
2006-11-01 14:19:33 +03:00
char * ou_str = NULL ;
2002-07-15 14:35:28 +04:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-25 18:57:34 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_group_usage ( c , argc , argv ) ;
2004-06-23 04:20:31 +04:00
}
2007-09-18 01:04:10 +04:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 18:57:34 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2002-07-15 14:35:28 +04:00
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ads_group_add: %s \n " ) , ads_errstr ( status ) ) ;
2022-05-25 18:57:34 +03:00
goto out ;
2002-07-15 14:35:28 +04:00
}
2007-09-18 01:04:10 +04:00
2002-07-15 14:35:28 +04:00
if ( ads_count_replies ( ads , res ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ads_group_add: Group %s already exists \n " ) , argv [ 0 ] ) ;
2022-05-25 18:57:34 +03:00
goto out ;
2002-07-15 14:35:28 +04:00
}
2008-05-10 01:22:12 +04:00
if ( c - > opt_container ) {
ou_str = SMB_STRDUP ( c - > opt_container ) ;
2006-11-01 14:19:33 +03:00
} else {
2010-07-01 01:09:05 +04:00
ou_str = ads_default_ou_string ( ads , DS_GUID_USERS_CONTAINER ) ;
2004-10-06 20:21:35 +04:00
}
2008-05-10 01:22:12 +04:00
status = ads_add_group_acct ( ads , argv [ 0 ] , ou_str , c - > opt_comment ) ;
2022-05-25 18:57:34 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Could not add group %s: %s \n " ) , argv [ 0 ] ,
2022-05-25 18:57:34 +03:00
ads_errstr ( status ) ) ;
goto out ;
2002-07-15 14:35:28 +04:00
}
2022-05-25 18:57:34 +03:00
d_printf ( _ ( " Group %s added \n " ) , argv [ 0 ] ) ;
ret = 0 ;
out :
ads_msgfree ( ads , res ) ;
2006-11-01 14:19:33 +03:00
SAFE_FREE ( ou_str ) ;
2022-05-25 18:57:34 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-07-15 14:35:28 +04:00
}
2008-05-10 01:22:12 +04:00
static int ads_group_delete ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
2022-05-25 19:02:11 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2006-11-01 13:59:28 +03:00
LDAPMessage * res = NULL ;
2022-05-25 19:02:11 +03:00
char * groupdn = NULL ;
int ret = - 1 ;
2002-07-15 14:35:28 +04:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-25 19:02:11 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_group_usage ( c , argc , argv ) ;
2004-06-23 04:20:31 +04:00
}
2007-09-18 01:04:10 +04:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 19:02:11 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2002-07-15 14:35:28 +04:00
2022-05-25 19:02:11 +03:00
status = ads_find_user_acct ( ads , & res , argv [ 0 ] ) ;
if ( ! ADS_ERR_OK ( status ) | | ads_count_replies ( ads , res ) ! = 1 ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Group %s does not exist. \n " ) , argv [ 0 ] ) ;
2022-05-25 19:02:11 +03:00
goto out ;
2002-07-15 14:35:28 +04:00
}
2022-05-25 19:02:11 +03:00
groupdn = ads_get_dn ( ads , tmp_ctx , res ) ;
if ( groupdn = = NULL ) {
goto out ;
}
status = ads_del_dn ( ads , groupdn ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " Error deleting group %s: %s \n " ) , argv [ 0 ] ,
ads_errstr ( status ) ) ;
goto out ;
2002-07-15 14:35:28 +04:00
}
2022-05-25 19:02:11 +03:00
d_printf ( _ ( " Group %s deleted \n " ) , argv [ 0 ] ) ;
ret = 0 ;
out :
ads_msgfree ( ads , res ) ;
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-07-15 14:35:28 +04:00
}
2008-05-10 01:22:12 +04:00
int net_ads_group ( struct net_context * c , int argc , const char * * argv )
2001-11-25 04:31:07 +03:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" add " ,
ads_group_add ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Add an AD group " ) ,
N_ ( " net ads group add \n "
" Add an AD group " )
2008-05-20 15:35:04 +04:00
} ,
{
" delete " ,
ads_group_delete ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Delete an AD group " ) ,
N_ ( " net ads group delete \n "
" Delete an AD group " )
2008-05-20 15:35:04 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2002-07-15 14:35:28 +04:00
} ;
2022-05-25 19:06:14 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
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 } ;
2022-05-25 19:06:14 +03:00
int ret = - 1 ;
2001-11-25 04:31:07 +03:00
2022-05-25 19:06:14 +03:00
if ( argc > = 0 ) {
TALLOC_FREE ( tmp_ctx ) ;
return net_run_function ( c , argc , argv , " net ads group " , func ) ;
}
2008-05-20 15:35:04 +04:00
2022-05-25 19:06:14 +03:00
if ( c - > display_usage ) {
d_printf ( " %s \n "
" net ads group \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " List AD groups " ) ) ;
net_display_usage_from_functable ( func ) ;
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2022-05-25 19:06:14 +03:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-25 19:06:14 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
}
2001-11-25 04:31:07 +03:00
2022-05-25 19:06:14 +03:00
if ( c - > opt_long_list_entries )
d_printf ( _ ( " \n Group name Comment "
" \n ----------------------------- \n " ) ) ;
2002-03-30 00:09:44 +03:00
2022-05-25 19:06:14 +03:00
status = ads_do_search_all_fn ( ads ,
ads - > config . bind_path ,
LDAP_SCOPE_SUBTREE ,
" (objectCategory=group) " ,
c - > opt_long_list_entries ?
longattrs : shortattrs ,
usergrp_display ,
disp_fields ) ;
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2002-07-15 14:35:28 +04:00
}
2022-05-25 19:06:14 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2001-11-25 04:31:07 +03:00
}
2008-05-10 01:22:12 +04:00
static int net_ads_status ( struct net_context * c , int argc , const char * * argv )
2001-11-25 04:31:07 +03:00
{
2022-05-26 10:10:06 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
LDAPMessage * res = NULL ;
int ret = - 1 ;
2001-11-25 04:31:07 +03:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads status \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Display machine account details " ) ) ;
2022-05-26 10:10:06 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 10:10:06 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2001-11-25 04:31:07 +03:00
2022-05-26 10:10:06 +03:00
status = ads_find_machine_acct ( ads , & res , lp_netbios_name ( ) ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_find_machine_acct: %s \n " ) ,
ads_errstr ( status ) ) ;
goto out ;
2001-11-25 04:06:56 +03:00
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
2022-05-26 10:10:06 +03:00
d_fprintf ( stderr , _ ( " No machine account for '%s' found \n " ) ,
lp_netbios_name ( ) ) ;
goto out ;
2001-11-25 04:06:56 +03:00
}
ads_dump ( ads , res ) ;
2022-05-26 10:10:06 +03:00
ret = 0 ;
out :
ads_msgfree ( ads , res ) ;
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2001-11-25 04:06:56 +03:00
}
2006-05-19 00:12:45 +04:00
/*******************************************************************
Leave an AD domain . Windows XP disables the machine account .
We ' ll try the same . The old code would do an LDAP delete .
That only worked using the machine creds because added the machine
with full control to the computer object ' s ACL .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-09-13 17:28:42 +04:00
2008-05-10 01:22:12 +04:00
static int net_ads_leave ( struct net_context * c , int argc , const char * * argv )
2001-11-25 04:06:56 +03:00
{
2022-05-26 10:18:11 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2008-02-28 13:55:36 +03:00
struct libnet_UnjoinCtx * r = NULL ;
WERROR werr ;
2022-05-26 10:18:11 +03:00
int ret = - 1 ;
2001-11-25 04:31:07 +03:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2018-06-27 18:32:31 +03:00
" net ads leave [--keep-account] \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Leave an AD domain " ) ) ;
2022-05-26 10:18:11 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2008-04-15 00:58:38 +04:00
if ( ! * lp_realm ( ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " No realm set, are we joined ? \n " ) ) ;
2022-05-26 10:18:11 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2006-05-19 00:12:45 +04:00
return - 1 ;
2002-03-10 04:52:09 +03:00
}
2009-07-05 11:21:07 +04:00
if ( ! c - > opt_kerberos ) {
2008-07-30 23:38:21 +04:00
use_in_memory_ccache ( ) ;
}
2006-05-19 00:12:45 +04:00
2010-12-15 21:57:23 +03:00
if ( ! c - > msg_ctx ) {
d_fprintf ( stderr , _ ( " Could not initialise message context. "
" Try running as root \n " ) ) ;
2022-05-26 10:18:11 +03:00
goto done ;
2010-12-15 21:57:23 +03:00
}
2022-05-26 10:18:11 +03:00
werr = libnet_init_UnjoinCtx ( tmp_ctx , & r ) ;
2008-02-28 13:55:36 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Could not initialise unjoin context. \n " ) ) ;
2022-05-26 10:18:11 +03:00
goto done ;
2001-11-25 03:18:11 +03:00
}
2008-03-07 20:18:35 +03:00
r - > in . debug = true ;
2009-07-05 11:21:07 +04:00
r - > in . use_kerberos = c - > opt_kerberos ;
2008-05-10 01:22:12 +04:00
r - > in . dc_name = c - > opt_host ;
2008-02-28 13:55:36 +03:00
r - > in . domain_name = lp_realm ( ) ;
2009-07-05 11:21:07 +04:00
r - > in . admin_account = c - > opt_user_name ;
r - > in . admin_password = net_prompt_pass ( c , c - > opt_user_name ) ;
2008-04-15 01:07:55 +04:00
r - > in . modify_config = lp_config_backend_is_registry ( ) ;
2009-06-19 21:46:07 +04:00
2009-07-30 01:28:01 +04:00
/* Try to delete it, but if that fails, disable it. The
2009-06-19 21:46:07 +04:00
WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE really means " disable */
2008-02-28 13:55:36 +03:00
r - > in . unjoin_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE ;
2018-06-27 18:32:31 +03:00
if ( c - > opt_keep_account ) {
r - > in . delete_machine_account = false ;
} else {
r - > in . delete_machine_account = true ;
}
2010-09-22 07:56:23 +04:00
r - > in . msg_ctx = c - > msg_ctx ;
2006-05-19 00:12:45 +04:00
2022-05-26 10:18:11 +03:00
werr = libnet_Unjoin ( tmp_ctx , r ) ;
2008-02-28 13:55:36 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Failed to leave domain: %s \n " ) ,
2008-02-28 16:08:32 +03:00
r - > out . error_string ? r - > out . error_string :
get_friendly_werror_msg ( werr ) ) ;
2006-05-19 00:12:45 +04:00
goto done ;
}
2007-09-18 01:04:10 +04:00
2009-06-19 21:46:07 +04:00
if ( r - > out . deleted_machine_account ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Deleted account for '%s' in realm '%s' \n " ) ,
2008-02-28 13:55:36 +03:00
r - > in . machine_name , r - > out . dns_domain_name ) ;
2022-05-26 10:18:11 +03:00
ret = 0 ;
2006-05-19 00:12:45 +04:00
goto done ;
}
2008-02-28 13:55:36 +03:00
/* We couldn't delete it - see if the disable succeeded. */
if ( r - > out . disabled_machine_account ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Disabled account for '%s' in realm '%s' \n " ) ,
2008-02-28 13:55:36 +03:00
r - > in . machine_name , r - > out . dns_domain_name ) ;
2022-05-26 10:18:11 +03:00
ret = 0 ;
2008-02-28 13:55:36 +03:00
goto done ;
2006-09-13 13:03:42 +04:00
}
2012-05-08 18:01:14 +04:00
/* Based on what we requested, we shouldn't get here, but if
2009-06-19 21:46:07 +04:00
we did , it means the secrets were removed , and therefore
we have left the domain */
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Machine '%s' Left domain '%s' \n " ) ,
2008-02-28 13:55:36 +03:00
r - > in . machine_name , r - > out . dns_domain_name ) ;
2006-09-13 17:28:42 +04:00
2022-05-26 10:18:11 +03:00
ret = 0 ;
2008-02-28 13:55:36 +03:00
done :
2022-05-26 10:18:11 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-08-17 18:45:04 +04:00
}
2022-05-26 10:25:34 +03:00
static ADS_STATUS net_ads_join_ok ( struct net_context * c )
2002-08-17 18:45:04 +04:00
{
2022-05-26 10:25:34 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2002-08-17 18:45:04 +04:00
ADS_STRUCT * ads = NULL ;
2006-08-18 16:45:51 +04:00
ADS_STATUS status ;
2009-12-16 23:22:50 +03:00
fstring dc_name ;
struct sockaddr_storage dcip ;
2002-08-17 18:45:04 +04:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
2022-05-26 10:25:34 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ADS_ERROR_NT ( NT_STATUS_ACCESS_DENIED ) ;
2002-08-17 18:45:04 +04:00
}
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2009-07-05 11:21:07 +04:00
net_use_krb_machine_account ( c ) ;
2001-11-25 03:18:11 +03:00
2009-12-16 23:22:50 +03:00
get_dc_name ( lp_workgroup ( ) , lp_realm ( ) , dc_name , & dcip ) ;
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2006-08-18 16:45:51 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2022-05-26 10:25:34 +03:00
goto out ;
2002-08-17 18:45:04 +04:00
}
2022-05-26 10:25:34 +03:00
status = ADS_ERROR_NT ( NT_STATUS_OK ) ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return status ;
2001-11-25 03:18:11 +03:00
}
2002-08-17 18:45:04 +04:00
/*
check that an existing join is OK
*/
2008-05-10 01:22:12 +04:00
int net_ads_testjoin ( struct net_context * c , int argc , const char * * argv )
2002-08-17 18:45:04 +04:00
{
2022-05-26 10:25:34 +03:00
ADS_STATUS status ;
2003-02-24 06:06:45 +03:00
use_in_memory_ccache ( ) ;
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads testjoin \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Test if the existing join is ok " ) ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2002-08-17 18:45:04 +04:00
/* Display success or failure */
2008-05-10 01:22:12 +04:00
status = net_ads_join_ok ( c ) ;
2022-05-26 10:25:34 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
fprintf ( stderr , _ ( " Join to domain is not valid: %s \n " ) ,
2022-05-26 10:25:34 +03:00
get_friendly_nt_error_msg ( ads_ntstatus ( status ) ) ) ;
2002-08-17 18:45:04 +04:00
return - 1 ;
}
2009-07-30 01:28:01 +04:00
printf ( _ ( " Join is OK \n " ) ) ;
2002-08-17 18:45:04 +04:00
return 0 ;
}
2006-05-12 19:17:35 +04:00
/*******************************************************************
2019-08-14 09:05:05 +03:00
Simple config checks before beginning the join
2006-05-12 19:17:35 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-12-17 14:16:22 +03:00
2008-04-14 18:13:52 +04:00
static WERROR check_ads_config ( void )
2006-05-12 19:17:35 +04:00
{
if ( lp_server_role ( ) ! = ROLE_DOMAIN_MEMBER ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Host is not configured as a member server. \n " ) ) ;
2008-04-14 18:13:52 +04:00
return WERR_INVALID_DOMAIN_ROLE ;
2006-04-18 17:22:14 +04:00
}
2011-06-09 09:31:03 +04:00
if ( strlen ( lp_netbios_name ( ) ) > 15 ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Our netbios name can be at most 15 chars long, "
2011-06-09 09:31:03 +04:00
" \" %s \" is %u chars long \n " ) , lp_netbios_name ( ) ,
( unsigned int ) strlen ( lp_netbios_name ( ) ) ) ;
2008-10-23 17:35:21 +04:00
return WERR_INVALID_COMPUTERNAME ;
2006-04-19 19:43:48 +04:00
}
2006-04-18 17:22:14 +04:00
2006-05-12 19:17:35 +04:00
if ( lp_security ( ) = = SEC_ADS & & ! * lp_realm ( ) ) {
2023-08-02 05:54:17 +03:00
d_fprintf ( stderr , _ ( " realm must be set in %s for ADS "
2009-07-30 01:28:01 +04:00
" join to succeed. \n " ) , get_dyn_CONFIGFILE ( ) ) ;
2015-12-03 17:24:26 +03:00
return WERR_INVALID_PARAMETER ;
2004-06-23 04:20:31 +04:00
}
2001-11-25 03:18:11 +03:00
2008-04-14 18:13:52 +04:00
return WERR_OK ;
2006-05-12 19:17:35 +04:00
}
2001-12-17 14:16:22 +03:00
2006-07-26 19:26:51 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-18 01:04:10 +04:00
2008-05-10 01:22:12 +04:00
static int net_ads_join_usage ( struct net_context * c , int argc , const char * * argv )
2006-07-26 19:26:51 +04:00
{
2015-09-09 09:28:43 +03:00
d_printf ( _ ( " net ads join [--no-dns-updates] [options] \n "
2009-07-30 01:28:01 +04:00
" Valid options: \n " ) ) ;
2020-05-27 16:54:12 +03:00
d_printf ( _ ( " dnshostname=FQDN Set the dnsHostName attribute during the join. \n "
" The default is in the form netbiosname.dnsdomain \n " ) ) ;
2015-09-09 09:58:43 +03:00
d_printf ( _ ( " createupn[=UPN] Set the userPrincipalName attribute during the join. \n "
" The default UPN is in the form host/netbiosname@REALM. \n " ) ) ;
d_printf ( _ ( " createcomputer=OU Precreate the computer account in a specific OU. \n "
" The OU string read from top to bottom without RDNs \n "
" and delimited by a '/'. \n "
" E.g. \" createcomputer=Computers/Servers/Unix \" \n "
" NB: A backslash ' \\ ' is used as escape at multiple \n "
" levels and may need to be doubled or even \n "
" quadrupled. It is not used as a separator. \n " ) ) ;
d_printf ( _ ( " machinepass=PASS Set the machine password to a specific value during \n "
" the join. The default password is random. \n " ) ) ;
d_printf ( _ ( " osName=string Set the operatingSystem attribute during the join. \n " ) ) ;
d_printf ( _ ( " osVer=string Set the operatingSystemVersion attribute during join. \n "
" NB: osName and osVer must be specified together for \n "
" either to take effect. The operatingSystemService \n "
" attribute is then also set along with the two \n "
" other attributes. \n " ) ) ;
d_printf ( _ ( " osServicePack=string Set the operatingSystemServicePack attribute \n "
" during the join. \n "
" NB: If not specified then by default the samba \n "
" version string is used instead. \n " ) ) ;
2006-07-26 19:26:51 +04:00
return - 1 ;
}
2012-01-31 19:16:47 +04:00
2008-05-10 01:22:12 +04:00
int net_ads_join ( struct net_context * c , int argc , const char * * argv )
2006-05-12 19:17:35 +04:00
{
2022-05-26 10:37:15 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2008-02-28 16:29:44 +03:00
struct libnet_JoinCtx * r = NULL ;
2008-02-28 16:18:03 +03:00
const char * domain = lp_realm ( ) ;
2015-12-03 17:24:39 +03:00
WERROR werr = WERR_NERR_SETUPNOTJOINED ;
2008-05-12 13:53:23 +04:00
bool createupn = false ;
2020-05-27 16:54:12 +03:00
const char * dnshostname = NULL ;
2006-07-20 18:39:06 +04:00
const char * machineupn = NULL ;
2013-02-28 15:59:48 +04:00
const char * machine_password = NULL ;
2006-07-20 18:39:06 +04:00
const char * create_in_ou = NULL ;
int i ;
2007-03-20 18:29:33 +03:00
const char * os_name = NULL ;
const char * os_version = NULL ;
2014-10-02 19:13:18 +04:00
const char * os_servicepack = NULL ;
2008-04-15 01:07:55 +04:00
bool modify_config = lp_config_backend_is_registry ( ) ;
2015-06-28 14:36:22 +03:00
enum libnetjoin_JoinDomNameType domain_name_type = JoinDomNameTypeDNS ;
2022-05-26 10:37:15 +03:00
int ret = - 1 ;
2007-09-18 01:04:10 +04:00
2022-05-26 10:37:15 +03:00
if ( c - > display_usage ) {
TALLOC_FREE ( tmp_ctx ) ;
2008-05-20 15:35:04 +04:00
return net_ads_join_usage ( c , argc , argv ) ;
2022-05-26 10:37:15 +03:00
}
2008-05-20 15:35:04 +04:00
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2008-04-15 01:07:55 +04:00
if ( ! modify_config ) {
werr = check_ads_config ( ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Invalid configuration. Exiting.... \n " ) ) ;
2008-04-15 01:07:55 +04:00
goto fail ;
}
2001-11-25 03:18:11 +03:00
}
2009-07-05 11:21:07 +04:00
if ( ! c - > opt_kerberos ) {
2008-07-30 23:38:21 +04:00
use_in_memory_ccache ( ) ;
}
2003-08-20 02:47:10 +04:00
2022-05-26 10:37:15 +03:00
werr = libnet_init_JoinCtx ( tmp_ctx , & r ) ;
2008-02-28 16:18:03 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2006-08-03 16:41:20 +04:00
goto fail ;
2001-11-25 03:18:11 +03:00
}
2006-07-20 18:39:06 +04:00
/* process additional command line args */
2007-09-18 01:04:10 +04:00
2006-07-20 18:39:06 +04:00
for ( i = 0 ; i < argc ; i + + ) {
2020-05-27 16:54:12 +03:00
if ( ! strncasecmp_m ( argv [ i ] , " dnshostname " , strlen ( " dnshostname " ) ) ) {
dnshostname = get_string_param ( argv [ i ] ) ;
}
else if ( ! strncasecmp_m ( argv [ i ] , " createupn " , strlen ( " createupn " ) ) ) {
2008-05-12 13:53:23 +04:00
createupn = true ;
2006-07-20 18:39:06 +04:00
machineupn = get_string_param ( argv [ i ] ) ;
}
2011-05-13 22:23:36 +04:00
else if ( ! strncasecmp_m ( argv [ i ] , " createcomputer " , strlen ( " createcomputer " ) ) ) {
2006-07-20 18:39:06 +04:00
if ( ( create_in_ou = get_string_param ( argv [ i ] ) ) = = NULL ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Please supply a valid OU path. \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2007-03-20 18:29:33 +03:00
goto fail ;
2007-09-18 01:04:10 +04:00
}
2007-03-20 18:29:33 +03:00
}
2011-05-13 22:23:36 +04:00
else if ( ! strncasecmp_m ( argv [ i ] , " osName " , strlen ( " osName " ) ) ) {
2007-03-20 18:29:33 +03:00
if ( ( os_name = get_string_param ( argv [ i ] ) ) = = NULL ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Please supply a operating system name. \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2007-03-20 18:29:33 +03:00
goto fail ;
2007-09-18 01:04:10 +04:00
}
2007-03-20 18:29:33 +03:00
}
2011-05-13 22:23:36 +04:00
else if ( ! strncasecmp_m ( argv [ i ] , " osVer " , strlen ( " osVer " ) ) ) {
2007-03-20 18:29:33 +03:00
if ( ( os_version = get_string_param ( argv [ i ] ) ) = = NULL ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Please supply a valid operating system version. \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2006-08-03 16:41:20 +04:00
goto fail ;
2007-09-18 01:04:10 +04:00
}
2006-07-20 18:39:06 +04:00
}
2014-10-02 19:13:18 +04:00
else if ( ! strncasecmp_m ( argv [ i ] , " osServicePack " , strlen ( " osServicePack " ) ) ) {
if ( ( os_servicepack = get_string_param ( argv [ i ] ) ) = = NULL ) {
d_fprintf ( stderr , _ ( " Please supply a valid servicepack identifier. \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2014-10-02 19:13:18 +04:00
goto fail ;
}
}
2013-02-28 15:59:48 +04:00
else if ( ! strncasecmp_m ( argv [ i ] , " machinepass " , strlen ( " machinepass " ) ) ) {
if ( ( machine_password = get_string_param ( argv [ i ] ) ) = = NULL ) {
d_fprintf ( stderr , _ ( " Please supply a valid password to set as trust account password. \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2013-02-28 15:59:48 +04:00
goto fail ;
}
2022-05-26 10:37:15 +03:00
} else {
2008-02-28 16:18:03 +03:00
domain = argv [ i ] ;
2015-06-28 14:36:22 +03:00
if ( strchr ( domain , ' . ' ) = = NULL ) {
domain_name_type = JoinDomNameTypeUnknown ;
} else {
domain_name_type = JoinDomNameTypeDNS ;
}
2006-05-13 08:39:19 +04:00
}
}
2008-04-14 18:16:25 +04:00
if ( ! * domain ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Please supply a valid domain name \n " ) ) ;
2015-12-03 17:24:26 +03:00
werr = WERR_INVALID_PARAMETER ;
2008-04-14 18:16:25 +04:00
goto fail ;
}
2010-12-15 21:57:23 +03:00
if ( ! c - > msg_ctx ) {
d_fprintf ( stderr , _ ( " Could not initialise message context. "
" Try running as root \n " ) ) ;
werr = WERR_ACCESS_DENIED ;
goto fail ;
}
2006-05-12 19:17:35 +04:00
/* Do the domain join here */
2008-02-28 16:18:03 +03:00
r - > in . domain_name = domain ;
2015-06-28 14:36:22 +03:00
r - > in . domain_name_type = domain_name_type ;
2008-02-28 16:18:03 +03:00
r - > in . create_upn = createupn ;
r - > in . upn = machineupn ;
2020-05-27 16:54:12 +03:00
r - > in . dnshostname = dnshostname ;
2008-02-28 16:18:03 +03:00
r - > in . account_ou = create_in_ou ;
r - > in . os_name = os_name ;
r - > in . os_version = os_version ;
2014-10-02 19:13:18 +04:00
r - > in . os_servicepack = os_servicepack ;
2008-05-10 01:22:12 +04:00
r - > in . dc_name = c - > opt_host ;
2009-07-05 11:21:07 +04:00
r - > in . admin_account = c - > opt_user_name ;
r - > in . admin_password = net_prompt_pass ( c , c - > opt_user_name ) ;
2013-02-28 15:59:48 +04:00
r - > in . machine_password = machine_password ;
2008-03-07 20:18:35 +03:00
r - > in . debug = true ;
2009-07-05 11:21:07 +04:00
r - > in . use_kerberos = c - > opt_kerberos ;
2008-04-15 01:07:55 +04:00
r - > in . modify_config = modify_config ;
2008-02-28 16:18:03 +03:00
r - > in . join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE |
WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED ;
2010-09-22 07:56:23 +04:00
r - > in . msg_ctx = c - > msg_ctx ;
2007-09-18 01:04:10 +04:00
2022-05-26 10:37:15 +03:00
werr = libnet_Join ( tmp_ctx , r ) ;
2015-12-03 17:24:36 +03:00
if ( W_ERROR_EQUAL ( werr , WERR_NERR_DCNOTFOUND ) & &
2011-02-26 19:53:16 +03:00
strequal ( domain , lp_realm ( ) ) ) {
r - > in . domain_name = lp_workgroup ( ) ;
2015-06-28 14:36:22 +03:00
r - > in . domain_name_type = JoinDomNameTypeNBT ;
2022-05-26 10:37:15 +03:00
werr = libnet_Join ( tmp_ctx , r ) ;
2011-02-26 19:53:16 +03:00
}
2008-02-28 16:18:03 +03:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2006-08-03 16:41:20 +04:00
goto fail ;
2003-09-05 21:57:45 +04:00
}
2006-11-17 02:48:46 +03:00
2006-05-12 19:17:35 +04:00
/* Check the short name of the domain */
2007-09-18 01:04:10 +04:00
2008-04-17 02:06:00 +04:00
if ( ! modify_config & & ! strequal ( lp_workgroup ( ) , r - > out . netbios_domain_name ) ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " The workgroup in %s does not match the short \n "
" domain name obtained from the server. \n "
" Using the name [%s] from the server. \n "
" You should set \" workgroup = %s \" in %s. \n " ) ,
get_dyn_CONFIGFILE ( ) , r - > out . netbios_domain_name ,
2008-02-28 16:18:03 +03:00
r - > out . netbios_domain_name , get_dyn_CONFIGFILE ( ) ) ;
2007-09-18 01:04:10 +04:00
}
2006-05-12 19:17:35 +04:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Using short domain name -- %s \n " ) , r - > out . netbios_domain_name ) ;
2006-05-12 19:17:35 +04:00
2008-04-17 02:06:00 +04:00
if ( r - > out . dns_domain_name ) {
2012-10-23 19:12:59 +04:00
d_printf ( _ ( " Joined '%s' to dns domain '%s' \n " ) , r - > in . machine_name ,
2008-04-17 02:06:00 +04:00
r - > out . dns_domain_name ) ;
} else {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Joined '%s' to domain '%s' \n " ) , r - > in . machine_name ,
2008-04-17 02:06:00 +04:00
r - > out . netbios_domain_name ) ;
}
2007-09-18 01:04:10 +04:00
2016-06-15 17:04:29 +03:00
/* print out informative error string in case there is one */
if ( r - > out . error_string ! = NULL ) {
d_printf ( " %s \n " , r - > out . error_string ) ;
}
2012-01-31 19:15:54 +04:00
/*
2015-09-09 09:28:43 +03:00
* We try doing the dns update ( if it was compiled in
* and if it was not disabled on the command line ) .
2012-01-31 19:15:54 +04:00
* If the dns update fails , we still consider the join
* operation as succeeded if we came this far .
*/
2015-09-09 09:28:43 +03:00
if ( ! c - > opt_no_dns_updates ) {
2022-05-26 10:37:15 +03:00
net_ads_join_dns_updates ( c , tmp_ctx , r ) ;
2015-09-09 09:28:43 +03:00
}
2010-12-22 05:11:40 +03:00
2022-05-26 10:37:15 +03:00
ret = 0 ;
2006-08-03 16:41:20 +04:00
fail :
2022-05-26 10:37:15 +03:00
if ( ret ! = 0 ) {
/* issue an overall failure message at the end. */
d_printf ( _ ( " Failed to join domain: %s \n " ) ,
r & & r - > out . error_string ? r - > out . error_string :
get_friendly_werror_msg ( werr ) ) ;
}
2006-08-24 19:43:32 +04:00
2022-05-26 10:37:15 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2006-08-24 19:43:32 +04:00
}
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-09-18 01:04:10 +04:00
2008-05-10 01:22:12 +04:00
static int net_ads_dns_register ( struct net_context * c , int argc , const char * * argv )
2006-08-24 19:43:32 +04:00
{
2021-03-25 00:48:28 +03:00
# if defined(HAVE_KRB5)
2022-05-26 13:08:45 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
2006-08-24 19:43:32 +04:00
ADS_STATUS status ;
2010-12-16 03:49:14 +03:00
NTSTATUS ntstatus ;
const char * hostname = NULL ;
2010-12-16 14:07:24 +03:00
const char * * addrs_list = NULL ;
2010-12-16 03:49:14 +03:00
struct sockaddr_storage * addrs = NULL ;
int num_addrs = 0 ;
int count ;
2022-05-26 13:08:45 +03:00
int ret = - 1 ;
2007-09-18 01:04:10 +04:00
2006-11-18 00:46:26 +03:00
# ifdef DEVELOPER
talloc_enable_leak_report ( ) ;
# endif
2007-09-18 01:04:10 +04:00
2010-12-16 14:07:24 +03:00
if ( argc < = 1 & & lp_clustering ( ) & & lp_cluster_addresses ( ) = = NULL ) {
2010-12-16 03:49:14 +03:00
d_fprintf ( stderr , _ ( " Refusing DNS updates with automatic "
" detection of addresses in a clustered "
" setup. \n " ) ) ;
c - > display_usage = true ;
}
if ( c - > display_usage ) {
2010-02-08 13:53:59 +03:00
d_printf ( " %s \n "
2023-02-16 21:20:14 +03:00
" net ads dns register [hostname [IP [IP...]]] "
" [--force] [--dns-ttl TTL] \n "
2010-02-08 13:53:59 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Register hostname with DNS \n " ) ) ;
2022-05-26 13:08:45 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2006-08-24 19:43:32 +04:00
return - 1 ;
}
2010-12-16 03:49:14 +03:00
if ( argc > = 1 ) {
hostname = argv [ 0 ] ;
}
if ( argc > 1 ) {
num_addrs = argc - 1 ;
2010-12-16 14:07:24 +03:00
addrs_list = & argv [ 1 ] ;
} else if ( lp_clustering ( ) ) {
addrs_list = lp_cluster_addresses ( ) ;
num_addrs = str_list_length ( addrs_list ) ;
}
if ( num_addrs > 0 ) {
2022-05-26 13:08:45 +03:00
addrs = talloc_zero_array ( tmp_ctx ,
struct sockaddr_storage ,
num_addrs ) ;
2010-12-16 03:49:14 +03:00
if ( addrs = = NULL ) {
d_fprintf ( stderr , _ ( " Error allocating memory! \n " ) ) ;
2022-05-26 13:08:45 +03:00
goto out ;
2010-12-16 03:49:14 +03:00
}
}
for ( count = 0 ; count < num_addrs ; count + + ) {
2010-12-16 14:07:24 +03:00
if ( ! interpret_string_addr ( & addrs [ count ] , addrs_list [ count ] , 0 ) ) {
2010-12-16 03:49:14 +03:00
d_fprintf ( stderr , " %s '%s'. \n " ,
_ ( " Cannot interpret address " ) ,
2010-12-16 14:07:24 +03:00
addrs_list [ count ] ) ;
2022-05-26 13:08:45 +03:00
goto out ;
2010-12-16 03:49:14 +03:00
}
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2006-11-18 00:46:26 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
DEBUG ( 1 , ( " error on ads_startup: %s \n " , ads_errstr ( status ) ) ) ;
2022-05-26 13:08:45 +03:00
goto out ;
2006-11-18 00:46:26 +03:00
}
2022-05-26 13:08:45 +03:00
ntstatus = net_update_dns_ext ( c ,
tmp_ctx ,
ads ,
hostname ,
addrs ,
num_addrs ,
false ) ;
2010-12-16 03:49:14 +03:00
if ( ! NT_STATUS_IS_OK ( ntstatus ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " DNS update failed! \n " ) ) ;
2022-05-26 13:08:45 +03:00
goto out ;
2006-08-24 19:43:32 +04:00
}
2007-09-18 01:04:10 +04:00
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Successfully registered hostname with DNS \n " ) ) ;
2006-08-24 19:43:32 +04:00
2022-05-26 13:08:45 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2007-09-18 01:04:10 +04:00
2022-05-26 13:08:45 +03:00
return ret ;
2006-08-24 19:43:32 +04:00
# else
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr ,
_ ( " DNS update support not enabled at compile time! \n " ) ) ;
2006-08-03 16:41:20 +04:00
return - 1 ;
2006-08-24 19:43:32 +04:00
# endif
2001-11-25 03:18:11 +03:00
}
2016-06-27 02:26:53 +03:00
static int net_ads_dns_unregister ( struct net_context * c ,
int argc ,
const char * * argv )
{
2021-03-25 00:48:28 +03:00
# if defined(HAVE_KRB5)
2022-05-26 13:11:16 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
2016-06-27 02:26:53 +03:00
ADS_STATUS status ;
NTSTATUS ntstatus ;
const char * hostname = NULL ;
2022-05-26 13:11:16 +03:00
int ret = - 1 ;
2016-06-27 02:26:53 +03:00
# ifdef DEVELOPER
talloc_enable_leak_report ( ) ;
# endif
if ( argc ! = 1 ) {
c - > display_usage = true ;
}
if ( c - > display_usage ) {
d_printf ( " %s \n "
" net ads dns unregister [hostname] \n "
" %s \n " ,
_ ( " Usage: " ) ,
2023-07-18 12:36:49 +03:00
_ ( " Remove all IP Address entries for a given \n "
2019-06-25 01:20:42 +03:00
" hostname from the Active Directory server. \n " ) ) ;
2022-05-26 13:11:16 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2016-06-27 02:26:53 +03:00
return - 1 ;
}
/* Get the hostname for un-registering */
hostname = argv [ 0 ] ;
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2016-06-27 02:26:53 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
DEBUG ( 1 , ( " error on ads_startup: %s \n " , ads_errstr ( status ) ) ) ;
2022-05-26 13:11:16 +03:00
goto out ;
2016-06-27 02:26:53 +03:00
}
2022-05-26 13:11:16 +03:00
ntstatus = net_update_dns_ext ( c ,
tmp_ctx ,
ads ,
hostname ,
NULL ,
0 ,
true ) ;
2016-06-27 02:26:53 +03:00
if ( ! NT_STATUS_IS_OK ( ntstatus ) ) {
d_fprintf ( stderr , _ ( " DNS update failed! \n " ) ) ;
2022-05-26 13:11:16 +03:00
goto out ;
2016-06-27 02:26:53 +03:00
}
d_fprintf ( stderr , _ ( " Successfully un-registered hostname from DNS \n " ) ) ;
2022-05-26 13:11:16 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2016-06-27 02:26:53 +03:00
2022-05-26 13:11:16 +03:00
return ret ;
2016-06-27 02:26:53 +03:00
# else
d_fprintf ( stderr ,
_ ( " DNS update support not enabled at compile time! \n " ) ) ;
return - 1 ;
# endif
}
2006-11-18 00:46:26 +03:00
2020-07-18 00:45:45 +03:00
static int net_ads_dns_async ( struct net_context * c , int argc , const char * * argv )
{
size_t num_names = 0 ;
char * * hostnames = NULL ;
size_t i = 0 ;
struct samba_sockaddr * addrs = NULL ;
NTSTATUS status ;
if ( argc ! = 1 | | c - > display_usage ) {
d_printf ( " %s \n "
" %s \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " net ads dns async <name> \n " ) ,
_ ( " Async look up hostname from the DNS server \n "
" hostname \t Name to look up \n " ) ) ;
return - 1 ;
}
status = ads_dns_lookup_a ( talloc_tos ( ) ,
argv [ 0 ] ,
& num_names ,
& hostnames ,
& addrs ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Looking up A record for %s got error %s \n " ,
argv [ 0 ] ,
nt_errstr ( status ) ) ;
return - 1 ;
}
d_printf ( " Async A record lookup - got %u names for %s \n " ,
( unsigned int ) num_names ,
argv [ 0 ] ) ;
for ( i = 0 ; i < num_names ; i + + ) {
char addr_buf [ INET6_ADDRSTRLEN ] ;
print_sockaddr ( addr_buf ,
sizeof ( addr_buf ) ,
& addrs [ i ] . u . ss ) ;
d_printf ( " hostname[%u] = %s, IPv4addr = %s \n " ,
( unsigned int ) i ,
hostnames [ i ] ,
addr_buf ) ;
}
# if defined(HAVE_IPV6)
status = ads_dns_lookup_aaaa ( talloc_tos ( ) ,
argv [ 0 ] ,
& num_names ,
& hostnames ,
& addrs ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Looking up AAAA record for %s got error %s \n " ,
argv [ 0 ] ,
nt_errstr ( status ) ) ;
return - 1 ;
}
d_printf ( " Async AAAA record lookup - got %u names for %s \n " ,
( unsigned int ) num_names ,
argv [ 0 ] ) ;
for ( i = 0 ; i < num_names ; i + + ) {
char addr_buf [ INET6_ADDRSTRLEN ] ;
print_sockaddr ( addr_buf ,
sizeof ( addr_buf ) ,
& addrs [ i ] . u . ss ) ;
d_printf ( " hostname[%u] = %s, IPv6addr = %s \n " ,
( unsigned int ) i ,
hostnames [ i ] ,
addr_buf ) ;
}
# endif
return 0 ;
}
2008-05-10 01:22:12 +04:00
static int net_ads_dns ( struct net_context * c , int argc , const char * argv [ ] )
2006-11-18 00:46:26 +03:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" register " ,
net_ads_dns_register ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Add host dns entry to AD " ) ,
N_ ( " net ads dns register \n "
" Add host dns entry to AD " )
2008-05-20 15:35:04 +04:00
} ,
2016-06-27 02:26:53 +03:00
{
" unregister " ,
net_ads_dns_unregister ,
NET_TRANSPORT_ADS ,
N_ ( " Remove host dns entry from AD " ) ,
N_ ( " net ads dns unregister \n "
" Remove host dns entry from AD " )
} ,
2020-07-18 00:45:45 +03:00
{
" async " ,
net_ads_dns_async ,
NET_TRANSPORT_ADS ,
N_ ( " Look up host " ) ,
N_ ( " net ads dns async \n "
" Look up host using async DNS " )
} ,
2008-05-20 15:35:04 +04:00
{ NULL , NULL , 0 , NULL , NULL }
2006-11-18 00:46:26 +03:00
} ;
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net ads dns " , func ) ;
2006-11-18 00:46:26 +03:00
}
2006-05-12 19:17:35 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-05-10 01:22:12 +04:00
int net_ads_printer_usage ( struct net_context * c , int argc , const char * * argv )
2002-02-02 05:06:03 +03:00
{
2009-07-30 01:28:01 +04:00
d_printf ( _ (
2003-07-03 09:08:51 +04:00
" \n net ads printer search <printer> "
2004-09-29 13:56:35 +04:00
" \n \t search for a printer in the directory \n "
2002-02-02 05:06:03 +03:00
" \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 "
2009-07-30 01:28:01 +04:00
" \n \t (note: printer name is required) \n " ) ) ;
2002-02-02 05:06:03 +03:00
return - 1 ;
}
2006-05-12 19:17:35 +04:00
/*******************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2022-05-26 13:23:17 +03:00
static int net_ads_printer_search ( struct net_context * c ,
int argc ,
const char * * argv )
2003-07-03 09:08:51 +04:00
{
2022-05-26 13:23:17 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 13:23:17 +03:00
int ret = - 1 ;
2003-07-03 09:08:51 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads printer search \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " List printers in the AD " ) ) ;
2022-05-26 13:23:17 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-26 13:23:17 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2003-07-03 09:08:51 +04:00
2022-05-26 13:23:17 +03:00
status = ads_find_printers ( ads , & res ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_find_printer: %s \n " ) ,
ads_errstr ( status ) ) ;
goto out ;
2003-07-03 09:08:51 +04:00
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " No results found \n " ) ) ;
2022-05-26 13:23:17 +03:00
goto out ;
2003-07-03 09:08:51 +04:00
}
ads_dump ( ads , res ) ;
2022-05-26 13:23:17 +03:00
ret = 0 ;
out :
2003-07-03 09:08:51 +04:00
ads_msgfree ( ads , res ) ;
2022-05-26 13:23:17 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2003-07-03 09:08:51 +04:00
}
2022-05-26 13:29:14 +03:00
static int net_ads_printer_info ( struct net_context * c ,
int argc ,
const char * * argv )
2002-02-02 05:06:03 +03:00
{
2022-05-26 13:29:14 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * servername = NULL ;
const char * printername = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 13:29:14 +03:00
int ret = - 1 ;
2002-02-02 05:06:03 +03:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads printer info [printername [servername]] \n "
2009-07-30 01:28:01 +04:00
" Display printer info from AD \n "
" printername \t Printer name or wildcard \n "
" servername \t Name of the print server \n " ) ) ;
2022-05-26 13:29:14 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-26 13:29:14 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2002-02-02 05:06:03 +03:00
2004-06-23 04:20:31 +04:00
if ( argc > 0 ) {
2002-02-02 05:06:03 +03:00
printername = argv [ 0 ] ;
2004-06-23 04:20:31 +04:00
} else {
2002-02-02 05:06:03 +03:00
printername = " * " ;
2004-06-23 04:20:31 +04:00
}
2002-02-02 05:06:03 +03:00
2004-06-23 04:20:31 +04:00
if ( argc > 1 ) {
2002-02-02 05:06:03 +03:00
servername = argv [ 1 ] ;
2004-06-23 04:20:31 +04:00
} else {
2011-06-09 09:31:03 +04:00
servername = lp_netbios_name ( ) ;
2004-06-23 04:20:31 +04:00
}
2002-02-02 05:06:03 +03:00
2022-05-26 13:29:14 +03:00
status = ads_find_printer_on_server ( ads , & res , printername , servername ) ;
if ( ! ADS_ERR_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Server '%s' not found: %s \n " ) ,
2022-05-26 13:29:14 +03:00
servername , ads_errstr ( status ) ) ;
goto out ;
2002-02-02 05:06:03 +03:00
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Printer '%s' not found \n " ) , printername ) ;
2022-05-26 13:29:14 +03:00
goto out ;
2002-02-02 05:06:03 +03:00
}
ads_dump ( ads , res ) ;
2022-05-26 13:29:14 +03:00
ret = 0 ;
out :
2002-03-30 00:09:44 +03:00
ads_msgfree ( ads , res ) ;
2022-05-26 13:29:14 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-02-02 05:06:03 +03:00
}
2022-05-26 13:40:32 +03:00
static int net_ads_printer_publish ( struct net_context * c ,
int argc ,
const char * * argv )
2002-02-02 05:06:03 +03:00
{
2022-05-26 13:40:32 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * servername = NULL ;
const char * printername = NULL ;
2009-11-13 00:56:33 +03:00
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_hnd = NULL ;
2022-05-26 13:40:32 +03:00
struct sockaddr_storage server_ss = { 0 } ;
2002-11-18 23:23:05 +03:00
NTSTATUS nt_status ;
2022-05-26 13:40:32 +03:00
ADS_MODLIST mods = NULL ;
char * prt_dn = NULL ;
char * srv_dn = NULL ;
char * * srv_cn = NULL ;
char * srv_cn_escaped = NULL ;
char * printername_escaped = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2015-12-23 13:32:04 +03:00
bool ok ;
2022-05-26 13:40:32 +03:00
int ret = - 1 ;
2002-02-02 05:06:03 +03:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads printer publish <printername> [servername] \n "
2009-07-30 01:28:01 +04:00
" Publish printer in AD \n "
" printername \t Name of the printer \n "
" servername \t Name of the print server \n " ) ) ;
2022-05-26 13:40:32 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 04:20:31 +04:00
return - 1 ;
}
2002-02-02 05:06:03 +03:00
2022-05-26 13:40:32 +03:00
mods = ads_init_mods ( tmp_ctx ) ;
if ( mods = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 13:40:32 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2007-09-18 01:04:10 +04:00
2003-07-03 09:58:55 +04:00
printername = argv [ 0 ] ;
2004-06-23 04:20:31 +04:00
if ( argc = = 2 ) {
2002-11-18 23:23:05 +03:00
servername = argv [ 1 ] ;
2004-06-23 04:20:31 +04:00
} else {
2011-06-09 09:31:03 +04:00
servername = lp_netbios_name ( ) ;
2004-06-23 04:20:31 +04:00
}
2007-09-18 01:04:10 +04:00
2003-07-03 09:58:55 +04:00
/* Get printer data from SPOOLSS */
2002-11-18 23:23:05 +03:00
2015-12-23 13:32:04 +03:00
ok = resolve_name ( servername , & server_ss , 0x20 , false ) ;
if ( ! ok ) {
d_fprintf ( stderr , _ ( " Could not find server %s \n " ) ,
servername ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2015-12-23 13:32:04 +03:00
}
2002-11-18 23:23:05 +03:00
2021-01-19 09:49:26 +03:00
cli_credentials_set_kerberos_state ( c - > creds ,
2020-08-19 16:46:11 +03:00
CRED_USE_KERBEROS_REQUIRED ,
CRED_SPECIFIED ) ;
2019-11-11 17:46:16 +03:00
nt_status = cli_full_connection_creds ( & cli , lp_netbios_name ( ) , servername ,
2007-10-25 01:16:54 +04:00
& server_ss , 0 ,
2007-09-18 01:04:10 +04:00
" IPC$ " , " IPC " ,
2021-01-19 09:49:26 +03:00
c - > creds ,
2020-06-04 15:59:14 +03:00
CLI_FULL_CONNECTION_IPC ) ;
2002-11-18 23:23:05 +03:00
2003-07-03 09:58:55 +04:00
if ( NT_STATUS_IS_ERR ( nt_status ) ) {
2011-03-01 00:04:29 +03:00
d_fprintf ( stderr , _ ( " Unable to open a connection to %s to "
2009-07-30 01:28:01 +04:00
" obtain data for %s \n " ) ,
servername , printername ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2003-07-03 09:58:55 +04:00
}
/* Publish on AD server */
ads_find_machine_acct ( ads , & res , servername ) ;
if ( ads_count_replies ( ads , res ) = = 0 ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Could not find machine account for server "
" %s \n " ) ,
2003-07-03 09:58:55 +04:00
servername ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2003-07-03 09:58:55 +04:00
}
2007-07-16 15:08:00 +04:00
srv_dn = ldap_get_dn ( ( LDAP * ) ads - > ldap . ld , ( LDAPMessage * ) res ) ;
2003-07-03 09:58:55 +04:00
srv_cn = ldap_explode_dn ( srv_dn , 1 ) ;
2007-03-01 03:49:28 +03:00
srv_cn_escaped = escape_rdn_val_string_alloc ( srv_cn [ 0 ] ) ;
printername_escaped = escape_rdn_val_string_alloc ( printername ) ;
if ( ! srv_cn_escaped | | ! printername_escaped ) {
2007-03-01 04:17:36 +03:00
SAFE_FREE ( srv_cn_escaped ) ;
SAFE_FREE ( printername_escaped ) ;
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Internal error, out of memory! " ) ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2007-03-01 03:49:28 +03:00
}
2022-05-26 13:40:32 +03:00
prt_dn = talloc_asprintf ( tmp_ctx ,
" cn=%s-%s,%s " ,
srv_cn_escaped ,
printername_escaped ,
srv_dn ) ;
if ( prt_dn = = NULL ) {
2009-01-01 05:06:57 +03:00
SAFE_FREE ( srv_cn_escaped ) ;
SAFE_FREE ( printername_escaped ) ;
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Internal error, out of memory! " ) ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2009-01-01 05:06:57 +03:00
}
2003-07-03 09:58:55 +04:00
2007-03-01 04:17:36 +03:00
SAFE_FREE ( srv_cn_escaped ) ;
SAFE_FREE ( printername_escaped ) ;
2013-05-24 15:29:28 +04:00
nt_status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_spoolss , & pipe_hnd ) ;
2008-07-20 13:04:31 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2011-03-01 00:04:29 +03:00
d_fprintf ( stderr , _ ( " Unable to open a connection to the spoolss pipe on %s \n " ) ,
2006-03-31 04:47:08 +04:00
servername ) ;
2022-05-26 13:40:32 +03:00
goto out ;
2006-03-31 04:47:08 +04:00
}
2022-05-26 13:40:32 +03:00
if ( ! W_ERROR_IS_OK ( get_remote_printer_publishing_data ( pipe_hnd ,
tmp_ctx ,
& mods ,
2006-09-06 16:29:45 +04:00
printername ) ) ) {
2022-05-26 13:40:32 +03:00
goto out ;
2006-09-06 16:29:45 +04:00
}
2002-11-18 23:23:05 +03:00
2022-05-26 13:40:32 +03:00
status = ads_add_printer_entry ( ads , prt_dn , tmp_ctx , & mods ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , " ads_publish_printer: %s \n " ,
ads_errstr ( status ) ) ;
goto out ;
2002-02-02 05:06:03 +03:00
}
2007-09-18 01:04:10 +04:00
2002-02-02 05:06:03 +03:00
d_printf ( " published printer \n " ) ;
2022-05-26 13:40:32 +03:00
ret = 0 ;
out :
talloc_destroy ( tmp_ctx ) ;
2007-09-18 01:04:10 +04:00
2022-05-26 13:40:32 +03:00
return ret ;
2002-02-02 05:06:03 +03:00
}
2022-05-26 13:46:05 +03:00
static int net_ads_printer_remove ( struct net_context * c ,
int argc ,
const char * * argv )
2002-02-02 05:06:03 +03:00
{
2022-05-26 13:46:05 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * servername = NULL ;
char * prt_dn = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 13:46:05 +03:00
int ret = - 1 ;
2002-02-02 05:06:03 +03:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads printer remove <printername> [servername] \n "
2009-07-30 01:28:01 +04:00
" Remove a printer from the AD \n "
" printername \t Name of the printer \n "
" servername \t Name of the print server \n " ) ) ;
2022-05-26 13:46:05 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 04:20:31 +04:00
return - 1 ;
}
2002-02-02 05:06:03 +03:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 13:46:05 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 04:20:31 +04:00
}
2002-02-02 05:06:03 +03:00
2004-06-23 04:20:31 +04:00
if ( argc > 1 ) {
2002-02-02 05:06:03 +03:00
servername = argv [ 1 ] ;
2004-06-23 04:20:31 +04:00
} else {
2011-06-09 09:31:03 +04:00
servername = lp_netbios_name ( ) ;
2004-06-23 04:20:31 +04:00
}
2002-02-02 05:06:03 +03:00
2022-05-26 13:46:05 +03:00
status = ads_find_printer_on_server ( ads , & res , argv [ 0 ] , servername ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_find_printer_on_server: %s \n " ) ,
ads_errstr ( status ) ) ;
goto out ;
2002-02-02 05:06:03 +03:00
}
if ( ads_count_replies ( ads , res ) = = 0 ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Printer '%s' not found \n " ) , argv [ 1 ] ) ;
2022-05-26 13:46:05 +03:00
goto out ;
2002-02-02 05:06:03 +03:00
}
2022-05-26 13:46:05 +03:00
prt_dn = ads_get_dn ( ads , tmp_ctx , res ) ;
if ( prt_dn = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
}
2002-02-02 05:06:03 +03:00
2022-05-26 13:46:05 +03:00
status = ads_del_dn ( ads , prt_dn ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " ads_del_dn: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2002-02-02 05:06:03 +03:00
}
2022-05-26 13:46:05 +03:00
ret = 0 ;
out :
ads_msgfree ( ads , res ) ;
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-02-02 05:06:03 +03:00
}
2008-05-10 01:22:12 +04:00
static int net_ads_printer ( struct net_context * c , int argc , const char * * argv )
2002-02-02 05:06:03 +03:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" search " ,
net_ads_printer_search ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Search for a printer " ) ,
N_ ( " net ads printer search \n "
" Search for a printer " )
2008-05-20 15:35:04 +04:00
} ,
{
" info " ,
net_ads_printer_info ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Display printer information " ) ,
N_ ( " net ads printer info \n "
" Display printer information " )
2008-05-20 15:35:04 +04:00
} ,
{
" publish " ,
net_ads_printer_publish ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Publish a printer " ) ,
N_ ( " net ads printer publish \n "
" Publish a printer " )
2008-05-20 15:35:04 +04:00
} ,
{
" remove " ,
net_ads_printer_remove ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Delete a printer " ) ,
N_ ( " net ads printer remove \n "
" Delete a printer " )
2008-05-20 15:35:04 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2002-02-02 05:06:03 +03:00
} ;
2007-09-18 01:04:10 +04:00
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net ads printer " , func ) ;
2002-02-02 05:06:03 +03:00
}
2001-12-20 06:54:52 +03:00
2008-05-10 01:22:12 +04:00
static int net_ads_password ( struct net_context * c , int argc , const char * * argv )
2001-12-20 06:54:52 +03:00
{
2022-05-26 14:08:01 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
2021-01-19 09:49:26 +03:00
const char * auth_principal = cli_credentials_get_username ( c - > creds ) ;
const char * auth_password = cli_credentials_get_password ( c - > creds ) ;
2011-06-02 01:50:49 +04:00
const char * realm = NULL ;
2022-05-26 14:08:01 +03:00
char * new_password = NULL ;
char * chr = NULL ;
char * prompt = NULL ;
const char * user = NULL ;
2012-11-22 18:51:33 +04:00
char pwd [ 256 ] = { 0 } ;
2022-05-26 14:08:01 +03:00
ADS_STATUS status ;
int ret = 0 ;
2004-06-23 01:58:35 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads password <username> \n "
2009-07-30 01:28:01 +04:00
" Change password for user \n "
" username \t Name of user to change password for \n " ) ) ;
2022-05-26 14:08:01 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2021-01-19 09:49:26 +03:00
if ( auth_principal = = NULL | | auth_password = = NULL ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " You must supply an administrator "
" username/password \n " ) ) ;
2022-05-26 14:08:01 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2009-07-05 11:21:07 +04:00
return - 1 ;
}
2003-06-10 08:15:55 +04:00
2004-06-23 01:58:35 +04:00
if ( argc < 1 ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ERROR: You must say which username to "
" change password for \n " ) ) ;
2022-05-26 14:08:01 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 01:58:35 +04:00
return - 1 ;
}
2022-05-26 14:08:01 +03:00
if ( strchr_m ( argv [ 0 ] , ' @ ' ) ) {
user = talloc_strdup ( tmp_ctx , argv [ 0 ] ) ;
} else {
user = talloc_asprintf ( tmp_ctx , " %s@%s " , argv [ 0 ] , lp_realm ( ) ) ;
}
if ( user = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
2004-06-23 01:58:35 +04:00
}
2007-09-18 01:04:10 +04:00
use_in_memory_ccache ( ) ;
2008-05-10 01:22:12 +04:00
chr = strchr_m ( auth_principal , ' @ ' ) ;
if ( chr ) {
realm = + + chr ;
2004-06-23 01:58:35 +04:00
} else {
realm = lp_realm ( ) ;
}
2007-09-18 01:04:10 +04:00
/* use the realm so we can eventually change passwords for users
2004-06-23 01:58:35 +04:00
in realms other than default */
2022-05-26 18:28:34 +03:00
ads = ads_init ( tmp_ctx ,
realm ,
c - > opt_workgroup ,
c - > opt_host ,
ADS_SASL_PLAIN ) ;
2019-08-13 18:41:40 +03:00
if ( ads = = NULL ) {
2022-05-26 14:08:01 +03:00
goto out ;
2004-06-23 01:58:35 +04:00
}
/* we don't actually need a full connect, but it's the easy way to
2023-07-18 12:36:49 +03:00
fill in the KDC ' s address */
2004-06-23 01:58:35 +04:00
ads_connect ( ads ) ;
2007-09-18 01:04:10 +04:00
2008-03-23 19:53:05 +03:00
if ( ! ads - > config . realm ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " Didn't find the kerberos server! \n " ) ) ;
2022-05-26 14:08:01 +03:00
goto out ;
2004-06-23 01:58:35 +04:00
}
2003-03-18 01:58:24 +03:00
2022-05-26 14:08:01 +03:00
if ( argv [ 1 ] ! = NULL ) {
new_password = talloc_strdup ( tmp_ctx , argv [ 1 ] ) ;
2004-06-23 01:58:35 +04:00
} else {
2012-11-22 18:51:33 +04:00
int rc ;
2022-05-26 14:08:01 +03:00
prompt = talloc_asprintf ( tmp_ctx , _ ( " Enter new password for %s: " ) , user ) ;
if ( prompt = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
2009-01-01 05:06:57 +03:00
}
2022-05-26 14:08:01 +03:00
2012-11-22 18:51:33 +04:00
rc = samba_getpass ( prompt , pwd , sizeof ( pwd ) , false , true ) ;
if ( rc < 0 ) {
2022-05-26 14:08:01 +03:00
goto out ;
2012-11-22 18:51:33 +04:00
}
2022-05-26 14:08:01 +03:00
new_password = talloc_strdup ( tmp_ctx , pwd ) ;
memset ( pwd , ' \0 ' , sizeof ( pwd ) ) ;
2004-06-23 01:58:35 +04:00
}
2001-12-20 06:54:52 +03:00
2022-05-26 14:08:01 +03:00
if ( new_password = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
}
status = kerberos_set_password ( ads - > auth . kdc_server ,
auth_principal ,
auth_password ,
user ,
new_password ,
ads - > auth . time_offset ) ;
memset ( new_password , ' \0 ' , strlen ( new_password ) ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " Password change failed: %s \n " ) ,
ads_errstr ( status ) ) ;
goto out ;
2004-06-23 01:58:35 +04:00
}
2001-12-20 06:54:52 +03:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Password change for %s completed. \n " ) , user ) ;
2001-12-20 06:54:52 +03:00
2022-05-26 14:08:01 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2001-12-20 06:54:52 +03:00
}
2008-05-10 01:22:12 +04:00
int net_ads_changetrustpw ( struct net_context * c , int argc , const char * * argv )
2007-09-18 01:04:10 +04:00
{
2022-05-26 14:14:50 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
char * host_principal = NULL ;
char * my_name = NULL ;
ADS_STATUS status ;
int ret = - 1 ;
2001-12-20 06:54:52 +03:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads changetrustpw \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Change the machine account's trust password " ) ) ;
2022-05-26 14:14:50 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2004-06-23 01:58:35 +04:00
if ( ! secrets_init ( ) ) {
DEBUG ( 1 , ( " Failed to initialise secrets database \n " ) ) ;
2022-05-26 14:14:50 +03:00
goto out ;
2004-06-23 01:58:35 +04:00
}
2002-08-17 18:45:04 +04:00
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2009-07-05 11:21:07 +04:00
net_use_krb_machine_account ( c ) ;
2002-08-17 18:45:04 +04:00
2004-06-23 01:58:35 +04:00
use_in_memory_ccache ( ) ;
2003-02-24 06:06:45 +03:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:14:50 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 01:58:35 +04:00
}
2022-05-26 14:14:50 +03:00
my_name = talloc_asprintf_strlower_m ( tmp_ctx , " %s " , lp_netbios_name ( ) ) ;
if ( my_name = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
2012-08-09 04:01:00 +04:00
}
2022-05-26 14:14:50 +03:00
host_principal = talloc_asprintf ( tmp_ctx , " %s$@%s " , my_name , ads - > config . realm ) ;
if ( host_principal = = NULL ) {
d_fprintf ( stderr , _ ( " Out of memory \n " ) ) ;
goto out ;
2009-01-01 05:06:57 +03:00
}
2004-06-23 01:58:35 +04:00
2022-05-26 14:14:50 +03:00
d_printf ( _ ( " Changing password for principal: %s \n " ) , host_principal ) ;
2001-12-20 06:54:52 +03:00
2022-05-26 14:14:50 +03:00
status = ads_change_trust_account_password ( ads , host_principal ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " Password change failed: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2004-06-23 01:58:35 +04:00
}
2007-09-18 01:04:10 +04:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Password change for principal %s succeeded. \n " ) , host_principal ) ;
2004-06-23 01:58:35 +04:00
2009-01-16 04:02:41 +03:00
if ( USE_SYSTEM_KEYTAB ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Attempting to update system keytab with new password. \n " ) ) ;
2004-06-23 01:58:35 +04:00
if ( ads_keytab_create_default ( ads ) ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Failed to update system keytab. \n " ) ) ;
2004-06-23 01:58:35 +04:00
}
}
2001-12-20 06:54:52 +03:00
2022-05-26 14:14:50 +03:00
ret = 0 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2001-12-20 06:54:52 +03:00
2022-05-26 14:14:50 +03:00
return ret ;
2001-12-20 06:54:52 +03:00
}
2002-07-15 14:35:28 +04:00
/*
help for net ads search
*/
2008-05-10 01:22:12 +04:00
static int net_ads_search_usage ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
2009-07-30 01:28:01 +04:00
d_printf ( _ (
2008-05-20 15:35:04 +04:00
" \n net ads search <expression> <attributes...> \n "
2008-06-24 17:55:30 +04:00
" \n Perform a raw LDAP search on a ADS server and dump the results. \n "
2008-05-20 15:35:04 +04:00
" The expression is a standard LDAP search expression, and the \n "
2008-06-24 17:55:30 +04:00
" attributes are a list of LDAP fields to show in the results. \n \n "
2002-07-15 14:35:28 +04:00
" Example: net ads search '(objectCategory=group)' sAMAccountName \n \n "
2009-07-30 01:28:01 +04:00
) ) ;
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2002-07-15 14:35:28 +04:00
return - 1 ;
}
/*
general ADS search function . Useful in diagnosing problems in ADS
*/
2008-05-10 01:22:12 +04:00
static int net_ads_search ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
2022-05-26 14:18:01 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * ldap_exp = NULL ;
const char * * attrs = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 14:18:01 +03:00
int ret = - 1 ;
2002-07-15 14:35:28 +04:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-26 14:18:01 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_search_usage ( c , argc , argv ) ;
2002-07-15 14:35:28 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-26 14:18:01 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2002-07-15 14:35:28 +04:00
}
2003-06-30 09:45:27 +04:00
ldap_exp = argv [ 0 ] ;
2002-07-15 14:35:28 +04:00
attrs = ( argv + 1 ) ;
2022-05-26 14:18:01 +03:00
status = ads_do_search_retry ( ads ,
ads - > config . bind_path ,
LDAP_SCOPE_SUBTREE ,
ldap_exp ,
attrs ,
& res ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " search failed: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2007-09-18 01:04:10 +04:00
}
2002-07-15 14:35:28 +04:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Got %d replies \n \n " ) , ads_count_replies ( ads , res ) ) ;
2002-07-15 14:35:28 +04:00
/* dump the results */
ads_dump ( ads , res ) ;
2022-05-26 14:18:01 +03:00
ret = 0 ;
out :
2002-07-15 14:35:28 +04:00
ads_msgfree ( ads , res ) ;
2022-05-26 14:18:01 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2002-07-15 14:35:28 +04:00
}
2003-03-18 01:33:34 +03:00
/*
help for net ads search
*/
2008-05-10 01:22:12 +04:00
static int net_ads_dn_usage ( struct net_context * c , int argc , const char * * argv )
2003-03-18 01:33:34 +03:00
{
2009-07-30 01:28:01 +04:00
d_printf ( _ (
2008-05-20 15:35:04 +04:00
" \n net ads dn <dn> <attributes...> \n "
" \n perform a raw LDAP search on a ADS server and dump the results \n "
" The DN standard LDAP DN, and the attributes are a list of LDAP fields \n "
" to show in the results \n \n "
2003-03-18 01:33:34 +03:00
" Example: net ads dn 'CN=administrator,CN=Users,DC=my,DC=domain' sAMAccountName \n \n "
2007-03-01 03:49:28 +03:00
" Note: the DN must be provided properly escaped. See RFC 4514 for details \n \n "
2009-07-30 01:28:01 +04:00
) ) ;
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2003-03-18 01:33:34 +03:00
return - 1 ;
}
/*
general ADS search function . Useful in diagnosing problems in ADS
*/
2008-05-10 01:22:12 +04:00
static int net_ads_dn ( struct net_context * c , int argc , const char * * argv )
2003-03-18 01:33:34 +03:00
{
2022-05-26 14:20:36 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * dn = NULL ;
const char * * attrs = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 14:20:36 +03:00
int ret = - 1 ;
2003-03-18 01:33:34 +03:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-26 14:20:36 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_dn_usage ( c , argc , argv ) ;
2003-03-18 01:33:34 +03:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-26 14:20:36 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2003-03-18 01:33:34 +03:00
}
dn = argv [ 0 ] ;
attrs = ( argv + 1 ) ;
2022-05-26 14:20:36 +03:00
status = ads_do_search_all ( ads ,
dn ,
LDAP_SCOPE_BASE ,
" (objectclass=*) " ,
attrs ,
& res ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " search failed: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2007-09-18 01:04:10 +04:00
}
2003-03-18 01:33:34 +03:00
d_printf ( " Got %d replies \n \n " , ads_count_replies ( ads , res ) ) ;
/* dump the results */
ads_dump ( ads , res ) ;
2022-05-26 14:20:36 +03:00
ret = 0 ;
out :
2003-03-18 01:33:34 +03:00
ads_msgfree ( ads , res ) ;
2022-05-26 14:20:36 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2003-03-18 01:33:34 +03:00
}
2006-04-28 18:44:43 +04:00
/*
help for net ads sid search
*/
2008-05-10 01:22:12 +04:00
static int net_ads_sid_usage ( struct net_context * c , int argc , const char * * argv )
2006-04-28 18:44:43 +04:00
{
2009-07-30 01:28:01 +04:00
d_printf ( _ (
2008-05-20 15:35:04 +04:00
" \n net ads sid <sid> <attributes...> \n "
" \n perform a raw LDAP search on a ADS server and dump the results \n "
" The SID is in string format, and the attributes are a list of LDAP fields \n "
" to show in the results \n \n "
2006-04-28 18:44:43 +04:00
" Example: net ads sid 'S-1-5-32' distinguishedName \n \n "
2009-07-30 01:28:01 +04:00
) ) ;
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2006-04-28 18:44:43 +04:00
return - 1 ;
}
/*
general ADS search function . Useful in diagnosing problems in ADS
*/
2008-05-10 01:22:12 +04:00
static int net_ads_sid ( struct net_context * c , int argc , const char * * argv )
2006-04-28 18:44:43 +04:00
{
2022-05-26 14:23:30 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
const char * sid_string = NULL ;
const char * * attrs = NULL ;
2006-09-04 01:07:16 +04:00
LDAPMessage * res = NULL ;
2022-05-26 14:23:30 +03:00
struct dom_sid sid = { 0 } ;
int ret = - 1 ;
2006-04-28 18:44:43 +04:00
2008-05-20 15:35:04 +04:00
if ( argc < 1 | | c - > display_usage ) {
2022-05-26 14:23:30 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2008-05-10 01:22:12 +04:00
return net_ads_sid_usage ( c , argc , argv ) ;
2006-04-28 18:44:43 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2022-05-26 14:23:30 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2006-04-28 18:44:43 +04:00
}
sid_string = argv [ 0 ] ;
attrs = ( argv + 1 ) ;
if ( ! string_to_sid ( & sid , sid_string ) ) {
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " could not convert sid \n " ) ) ;
2022-05-26 14:23:30 +03:00
goto out ;
2006-04-28 18:44:43 +04:00
}
2022-05-26 14:23:30 +03:00
status = ads_search_retry_sid ( ads , & res , & sid , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_fprintf ( stderr , _ ( " search failed: %s \n " ) , ads_errstr ( status ) ) ;
goto out ;
2007-09-18 01:04:10 +04:00
}
2006-04-28 18:44:43 +04:00
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Got %d replies \n \n " ) , ads_count_replies ( ads , res ) ) ;
2006-04-28 18:44:43 +04:00
/* dump the results */
ads_dump ( ads , res ) ;
2022-05-26 14:23:30 +03:00
ret = 0 ;
out :
2006-04-28 18:44:43 +04:00
ads_msgfree ( ads , res ) ;
2022-05-26 14:23:30 +03:00
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
2006-04-28 18:44:43 +04:00
}
2022-05-26 14:25:40 +03:00
static int net_ads_keytab_flush ( struct net_context * c ,
int argc ,
const char * * argv )
2004-06-23 01:58:35 +04:00
{
2022-05-26 14:25:40 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
int ret = - 1 ;
2004-06-23 01:58:35 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads keytab flush \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Delete the whole keytab " ) ) ;
2022-05-26 14:25:40 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2021-03-29 14:16:28 +03:00
if ( ! c - > opt_user_specified & & c - > opt_password = = NULL ) {
net_use_krb_machine_account ( c ) ;
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:25:40 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 01:58:35 +04:00
}
2022-05-26 14:25:40 +03:00
2004-06-23 01:58:35 +04:00
ret = ads_keytab_flush ( ads ) ;
2022-05-26 14:25:40 +03:00
out :
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 01:58:35 +04:00
return ret ;
}
2018-02-09 17:03:33 +03:00
static int net_ads_keytab_add ( struct net_context * c ,
int argc ,
const char * * argv ,
bool update_ads )
2004-06-23 01:58:35 +04:00
{
2022-05-26 14:29:56 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
2004-06-23 01:58:35 +04:00
int i ;
2022-05-26 14:29:56 +03:00
int ret = - 1 ;
2004-06-23 01:58:35 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads keytab add <principal> [principal ...] \n "
2009-07-30 01:28:01 +04:00
" Add principals to local keytab \n "
" principal \t Kerberos principal to add to "
" keytab \n " ) ) ;
2022-05-26 14:29:56 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " Processing principals to add... \n " ) ) ;
2021-03-29 14:16:28 +03:00
if ( ! c - > opt_user_specified & & c - > opt_password = = NULL ) {
net_use_krb_machine_account ( c ) ;
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:29:56 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 01:58:35 +04:00
}
2022-05-26 14:29:56 +03:00
for ( ret = 0 , i = 0 ; i < argc ; i + + ) {
2018-02-09 17:03:33 +03:00
ret | = ads_keytab_add_entry ( ads , argv [ i ] , update_ads ) ;
2004-06-23 01:58:35 +04:00
}
2022-05-26 14:29:56 +03:00
out :
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 01:58:35 +04:00
return ret ;
}
2018-02-09 17:03:33 +03:00
static int net_ads_keytab_add_default ( struct net_context * c ,
int argc ,
const char * * argv )
{
return net_ads_keytab_add ( c , argc , argv , false ) ;
}
static int net_ads_keytab_add_update_ads ( struct net_context * c ,
int argc ,
const char * * argv )
{
return net_ads_keytab_add ( c , argc , argv , true ) ;
}
2022-10-26 12:36:44 +03:00
static int net_ads_keytab_delete ( struct net_context * c ,
int argc ,
const char * * argv )
{
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
int i ;
int ret = - 1 ;
if ( c - > display_usage ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads keytab delete <principal> [principal ...] \n "
" Remove entries for service principal, "
" from the keytab file only. "
" Remove principals from local keytab \n "
" principal \t Kerberos principal to remove from "
" keytab \n " ) ) ;
TALLOC_FREE ( tmp_ctx ) ;
return - 1 ;
}
d_printf ( _ ( " Processing principals to delete... \n " ) ) ;
if ( ! c - > opt_user_specified & & c - > opt_password = = NULL ) {
net_use_krb_machine_account ( c ) ;
}
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
}
for ( ret = 0 , i = 0 ; i < argc ; i + + ) {
ret | = ads_keytab_delete_entry ( ads , argv [ i ] ) ;
}
out :
TALLOC_FREE ( tmp_ctx ) ;
return ret ;
}
2008-05-10 01:22:12 +04:00
static int net_ads_keytab_create ( struct net_context * c , int argc , const char * * argv )
2004-06-23 01:58:35 +04:00
{
2022-05-26 14:31:57 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
ADS_STRUCT * ads = NULL ;
ADS_STATUS status ;
int ret = - 1 ;
2004-06-23 01:58:35 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads keytab create \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Create new default keytab " ) ) ;
2022-05-26 14:31:57 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2022-11-30 18:16:05 +03:00
net_warn_member_options ( ) ;
2021-03-29 14:16:28 +03:00
if ( ! c - > opt_user_specified & & c - > opt_password = = NULL ) {
net_use_krb_machine_account ( c ) ;
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:31:57 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2004-06-23 01:58:35 +04:00
}
2022-05-26 14:31:57 +03:00
2004-06-23 01:58:35 +04:00
ret = ads_keytab_create_default ( ads ) ;
2022-05-26 14:31:57 +03:00
out :
TALLOC_FREE ( tmp_ctx ) ;
2004-06-23 01:58:35 +04:00
return ret ;
}
2008-05-10 01:22:12 +04:00
static int net_ads_keytab_list ( struct net_context * c , int argc , const char * * argv )
2007-04-23 12:40:54 +04:00
{
2007-06-29 13:01:29 +04:00
const char * keytab = NULL ;
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads keytab list [keytab] \n "
2009-07-30 01:28:01 +04:00
" List a local keytab \n "
" keytab \t Keytab to list \n " ) ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2007-06-29 13:01:29 +04:00
if ( argc > = 1 ) {
keytab = argv [ 0 ] ;
}
return ads_keytab_list ( keytab ) ;
2007-04-23 12:40:54 +04:00
}
2008-05-10 01:22:12 +04:00
int net_ads_keytab ( struct net_context * c , int argc , const char * * argv )
2004-06-23 01:58:35 +04:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" add " ,
2018-02-09 17:03:33 +03:00
net_ads_keytab_add_default ,
2008-05-20 15:35:04 +04:00
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Add a service principal " ) ,
N_ ( " net ads keytab add \n "
2018-02-09 17:03:33 +03:00
" Add a service principal, updates keytab file only. " )
} ,
2022-10-26 12:36:44 +03:00
{
" delete " ,
net_ads_keytab_delete ,
NET_TRANSPORT_ADS ,
N_ ( " Delete a service principal " ) ,
N_ ( " net ads keytab delete \n "
" Remove entries for service principal, from the keytab file only. " )
} ,
2018-02-09 17:03:33 +03:00
{
" add_update_ads " ,
net_ads_keytab_add_update_ads ,
NET_TRANSPORT_ADS ,
N_ ( " Add a service principal " ) ,
N_ ( " net ads keytab add_update_ads \n "
" Add a service principal, depending on the param passed may update ADS computer object in addition to the keytab file. " )
2008-05-20 15:35:04 +04:00
} ,
{
" create " ,
net_ads_keytab_create ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Create a fresh keytab " ) ,
N_ ( " net ads keytab create \n "
2019-08-29 22:32:30 +03:00
" Create a fresh keytab or update existing one. " )
2008-05-20 15:35:04 +04:00
} ,
{
" flush " ,
net_ads_keytab_flush ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Remove all keytab entries " ) ,
N_ ( " net ads keytab flush \n "
" Remove all keytab entries " )
2008-05-20 15:35:04 +04:00
} ,
{
" list " ,
net_ads_keytab_list ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " List a keytab " ) ,
N_ ( " net ads keytab list \n "
" List a keytab " )
2008-05-20 15:35:04 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2004-06-23 01:58:35 +04:00
} ;
2009-01-16 04:02:41 +03:00
if ( ! USE_KERBEROS_KEYTAB ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " \n Warning: \" kerberos method \" must be set to a "
" keytab method to use keytab functions. \n " ) ) ;
2004-06-23 01:58:35 +04:00
}
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net ads keytab " , func ) ;
2004-06-23 01:58:35 +04:00
}
2003-03-18 01:33:34 +03:00
2008-05-20 15:35:04 +04:00
static int net_ads_kerberos_renew ( struct net_context * c , int argc , const char * * argv )
2007-07-19 17:47:53 +04:00
{
2008-05-20 15:35:04 +04:00
int ret = - 1 ;
2007-07-19 17:47:53 +04:00
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads kerberos renew \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Renew TGT from existing credential cache " ) ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2007-07-19 17:47:53 +04:00
2008-05-20 15:35:04 +04:00
ret = smb_krb5_renew_ticket ( NULL , NULL , NULL , NULL ) ;
2007-07-19 17:47:53 +04:00
if ( ret ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " failed to renew kerberos ticket: %s \n " ) ,
2007-07-19 17:47:53 +04:00
error_message ( ret ) ) ;
}
return ret ;
}
2014-03-11 21:14:39 +04:00
static int net_ads_kerberos_pac_common ( struct net_context * c , int argc , const char * * argv ,
struct PAC_DATA_CTR * * pac_data_ctr )
2007-07-19 17:47:53 +04:00
{
NTSTATUS status ;
int ret = - 1 ;
2008-10-13 19:28:39 +04:00
const char * impersonate_princ_s = NULL ;
2014-01-17 17:29:03 +04:00
const char * local_service = NULL ;
2014-03-10 18:11:18 +04:00
int i ;
2007-07-19 17:47:53 +04:00
2014-03-10 18:11:18 +04:00
for ( i = 0 ; i < argc ; i + + ) {
if ( strnequal ( argv [ i ] , " impersonate " , strlen ( " impersonate " ) ) ) {
impersonate_princ_s = get_string_param ( argv [ i ] ) ;
if ( impersonate_princ_s = = NULL ) {
return - 1 ;
}
}
2014-03-11 19:34:36 +04:00
if ( strnequal ( argv [ i ] , " local_service " , strlen ( " local_service " ) ) ) {
local_service = get_string_param ( argv [ i ] ) ;
if ( local_service = = NULL ) {
return - 1 ;
}
}
2014-03-10 18:11:18 +04:00
}
2014-01-17 17:29:03 +04:00
if ( local_service = = NULL ) {
2014-03-11 21:14:39 +04:00
local_service = talloc_asprintf ( c , " %s$@%s " ,
2014-03-11 19:34:36 +04:00
lp_netbios_name ( ) , lp_realm ( ) ) ;
if ( local_service = = NULL ) {
goto out ;
}
2014-01-17 17:29:03 +04:00
}
2009-07-05 11:21:07 +04:00
c - > opt_password = net_prompt_pass ( c , c - > opt_user_name ) ;
2007-07-19 17:47:53 +04:00
2014-03-11 21:14:39 +04:00
status = kerberos_return_pac ( c ,
2009-07-05 11:21:07 +04:00
c - > opt_user_name ,
c - > opt_password ,
2010-05-06 06:45:14 +04:00
0 ,
2007-08-14 23:47:57 +04:00
NULL ,
NULL ,
2009-11-06 14:51:29 +03:00
NULL ,
2008-05-10 01:22:12 +04:00
true ,
true ,
2007-08-14 23:47:57 +04:00
2592000 , /* one month */
2008-10-13 19:28:39 +04:00
impersonate_princ_s ,
2014-01-17 17:29:03 +04:00
local_service ,
2022-02-22 15:08:56 +03:00
NULL ,
NULL ,
2014-03-11 21:14:39 +04:00
pac_data_ctr ) ;
2007-07-19 17:47:53 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " failed to query kerberos PAC: %s \n " ) ,
2007-07-19 17:47:53 +04:00
nt_errstr ( status ) ) ;
goto out ;
}
2014-03-11 21:14:39 +04:00
ret = 0 ;
out :
return ret ;
}
2014-03-11 21:07:11 +04:00
2014-03-11 21:14:39 +04:00
static int net_ads_kerberos_pac_dump ( struct net_context * c , int argc , const char * * argv )
{
struct PAC_DATA_CTR * pac_data_ctr = NULL ;
2020-06-14 11:45:39 +03:00
int i , num_buffers ;
2014-03-11 21:14:39 +04:00
int ret = - 1 ;
enum PAC_TYPE type = 0 ;
2014-02-21 21:56:04 +04:00
2014-03-11 21:14:39 +04:00
if ( c - > display_usage ) {
d_printf ( " %s \n "
" net ads kerberos pac dump [impersonate=string] [local_service=string] [pac_buffer_type=int] \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Dump the Kerberos PAC " ) ) ;
return - 1 ;
}
for ( i = 0 ; i < argc ; i + + ) {
if ( strnequal ( argv [ i ] , " pac_buffer_type " , strlen ( " pac_buffer_type " ) ) ) {
type = get_int_param ( argv [ i ] ) ;
2014-02-21 21:56:04 +04:00
}
2014-03-11 21:14:39 +04:00
}
2014-02-21 21:56:04 +04:00
2014-03-11 21:14:39 +04:00
ret = net_ads_kerberos_pac_common ( c , argc , argv , & pac_data_ctr ) ;
if ( ret ) {
return ret ;
}
if ( type = = 0 ) {
char * s = NULL ;
s = NDR_PRINT_STRUCT_STRING ( c , PAC_DATA ,
pac_data_ctr - > pac_data ) ;
if ( s ! = NULL ) {
d_printf ( _ ( " The Pac: %s \n " ) , s ) ;
talloc_free ( s ) ;
2014-02-21 21:56:04 +04:00
}
2014-03-11 21:14:39 +04:00
return 0 ;
2014-02-21 21:56:04 +04:00
}
2020-06-14 11:45:39 +03:00
num_buffers = pac_data_ctr - > pac_data - > num_buffers ;
for ( i = 0 ; i < num_buffers ; i + + ) {
2014-03-11 21:14:39 +04:00
char * s = NULL ;
if ( pac_data_ctr - > pac_data - > buffers [ i ] . type ! = type ) {
continue ;
}
s = NDR_PRINT_UNION_STRING ( c , PAC_INFO , type ,
pac_data_ctr - > pac_data - > buffers [ i ] . info ) ;
if ( s ! = NULL ) {
d_printf ( _ ( " The Pac: %s \n " ) , s ) ;
talloc_free ( s ) ;
}
break ;
2007-07-19 17:47:53 +04:00
}
2014-03-11 21:14:39 +04:00
return 0 ;
}
2014-03-11 21:16:40 +04:00
static int net_ads_kerberos_pac_save ( struct net_context * c , int argc , const char * * argv )
{
struct PAC_DATA_CTR * pac_data_ctr = NULL ;
char * filename = NULL ;
int ret = - 1 ;
int i ;
if ( c - > display_usage ) {
d_printf ( " %s \n "
" net ads kerberos pac save [impersonate=string] [local_service=string] [filename=string] \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Save the Kerberos PAC " ) ) ;
return - 1 ;
}
for ( i = 0 ; i < argc ; i + + ) {
if ( strnequal ( argv [ i ] , " filename " , strlen ( " filename " ) ) ) {
filename = get_string_param ( argv [ i ] ) ;
if ( filename = = NULL ) {
return - 1 ;
}
}
}
ret = net_ads_kerberos_pac_common ( c , argc , argv , & pac_data_ctr ) ;
if ( ret ) {
return ret ;
}
if ( filename = = NULL ) {
d_printf ( _ ( " please define \" filename=<filename> \" to save the PAC \n " ) ) ;
return - 1 ;
}
/* save the raw format */
if ( ! file_save ( filename , pac_data_ctr - > pac_blob . data , pac_data_ctr - > pac_blob . length ) ) {
d_printf ( _ ( " failed to save PAC in %s \n " ) , filename ) ;
return - 1 ;
}
return 0 ;
}
2014-03-11 21:14:39 +04:00
static int net_ads_kerberos_pac ( struct net_context * c , int argc , const char * * argv )
{
struct functable func [ ] = {
{
" dump " ,
net_ads_kerberos_pac_dump ,
NET_TRANSPORT_ADS ,
N_ ( " Dump Kerberos PAC " ) ,
N_ ( " net ads kerberos pac dump \n "
" Dump a Kerberos PAC to stdout " )
} ,
2014-03-11 21:16:40 +04:00
{
" save " ,
net_ads_kerberos_pac_save ,
NET_TRANSPORT_ADS ,
N_ ( " Save Kerberos PAC " ) ,
N_ ( " net ads kerberos pac save \n "
" Save a Kerberos PAC in a file " )
} ,
2014-03-11 21:14:39 +04:00
{ NULL , NULL , 0 , NULL , NULL }
} ;
return net_run_function ( c , argc , argv , " net ads kerberos pac " , func ) ;
2007-07-19 17:47:53 +04:00
}
2008-05-10 01:22:12 +04:00
static int net_ads_kerberos_kinit ( struct net_context * c , int argc , const char * * argv )
2007-07-19 17:47:53 +04:00
{
int ret = - 1 ;
NTSTATUS status ;
2008-05-20 15:35:04 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-07-30 01:28:01 +04:00
" net ads kerberos kinit \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Get Ticket Granting Ticket (TGT) for the user " ) ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2008-05-20 15:35:04 +04:00
}
2009-07-05 11:21:07 +04:00
c - > opt_password = net_prompt_pass ( c , c - > opt_user_name ) ;
2007-07-19 17:47:53 +04:00
2009-07-05 11:21:07 +04:00
ret = kerberos_kinit_password_ext ( c - > opt_user_name ,
c - > opt_password ,
2007-07-19 17:47:53 +04:00
0 ,
NULL ,
NULL ,
NULL ,
2008-05-10 01:22:12 +04:00
true ,
true ,
2007-07-19 17:47:53 +04:00
2592000 , /* one month */
2019-09-16 18:14:11 +03:00
NULL ,
NULL ,
NULL ,
2007-07-19 17:47:53 +04:00
& status ) ;
if ( ret ) {
2009-07-30 01:28:01 +04:00
d_printf ( _ ( " failed to kinit password: %s \n " ) ,
2007-07-19 17:47:53 +04:00
nt_errstr ( status ) ) ;
}
return ret ;
}
2008-05-10 01:22:12 +04:00
int net_ads_kerberos ( struct net_context * c , int argc , const char * * argv )
2007-07-19 17:47:53 +04:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" kinit " ,
net_ads_kerberos_kinit ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Retrieve Ticket Granting Ticket (TGT) " ) ,
N_ ( " net ads kerberos kinit \n "
" Receive Ticket Granting Ticket (TGT) " )
2008-05-20 15:35:04 +04:00
} ,
{
" renew " ,
net_ads_kerberos_renew ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Renew Ticket Granting Ticket from credential cache " ) ,
N_ ( " net ads kerberos renew \n "
" Renew Ticket Granting Ticket (TGT) from "
" credential cache " )
2008-05-20 15:35:04 +04:00
} ,
{
" pac " ,
net_ads_kerberos_pac ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Dump Kerberos PAC " ) ,
N_ ( " net ads kerberos pac \n "
" Dump Kerberos PAC " )
2008-05-20 15:35:04 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2007-07-19 17:47:53 +04:00
} ;
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net ads kerberos " , func ) ;
2002-04-04 06:53:42 +04:00
}
2001-12-20 06:54:52 +03:00
2022-05-26 14:35:11 +03:00
static int net_ads_setspn_list ( struct net_context * c ,
int argc ,
const char * * argv )
2018-01-24 17:26:03 +03:00
{
2022-05-26 14:35:11 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2018-01-24 17:26:03 +03:00
ADS_STRUCT * ads = NULL ;
2022-05-26 14:35:11 +03:00
ADS_STATUS status ;
bool ok = false ;
int ret = - 1 ;
2018-01-24 17:26:03 +03:00
if ( c - > display_usage ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads setspn list <machinename> \n " ) ) ;
2022-05-26 14:35:11 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2018-01-24 17:26:03 +03:00
}
2022-05-26 14:35:11 +03:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:35:11 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2018-01-24 17:26:03 +03:00
}
2022-05-26 14:35:11 +03:00
2018-01-24 17:26:03 +03:00
if ( argc ) {
ok = ads_setspn_list ( ads , argv [ 0 ] ) ;
} else {
ok = ads_setspn_list ( ads , lp_netbios_name ( ) ) ;
}
2022-05-26 14:35:11 +03:00
ret = ok ? 0 : - 1 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2018-01-24 17:26:03 +03:00
return ret ;
}
2018-01-24 17:41:06 +03:00
static int net_ads_setspn_add ( struct net_context * c , int argc , const char * * argv )
{
2022-05-26 14:37:31 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2018-01-24 17:41:06 +03:00
ADS_STRUCT * ads = NULL ;
2022-05-26 14:37:31 +03:00
ADS_STATUS status ;
bool ok = false ;
int ret = - 1 ;
2018-01-24 17:41:06 +03:00
if ( c - > display_usage | | argc < 1 ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads setspn add <machinename> SPN \n " ) ) ;
2022-05-26 14:37:31 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2018-01-24 17:41:06 +03:00
}
2022-05-26 14:37:31 +03:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:37:31 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2018-01-24 17:41:06 +03:00
}
2022-05-26 14:37:31 +03:00
2018-01-24 17:41:06 +03:00
if ( argc > 1 ) {
ok = ads_setspn_add ( ads , argv [ 0 ] , argv [ 1 ] ) ;
} else {
ok = ads_setspn_add ( ads , lp_netbios_name ( ) , argv [ 0 ] ) ;
}
2022-05-26 14:37:31 +03:00
ret = ok ? 0 : - 1 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2018-01-24 17:41:06 +03:00
return ret ;
}
2018-01-24 17:51:03 +03:00
static int net_ads_setspn_delete ( struct net_context * c , int argc , const char * * argv )
{
2022-05-26 14:41:43 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2018-01-24 17:51:03 +03:00
ADS_STRUCT * ads = NULL ;
2022-05-26 14:41:43 +03:00
ADS_STATUS status ;
bool ok = false ;
int ret = - 1 ;
2018-01-24 17:51:03 +03:00
if ( c - > display_usage | | argc < 1 ) {
d_printf ( " %s \n %s " ,
_ ( " Usage: " ) ,
_ ( " net ads setspn delete <machinename> SPN \n " ) ) ;
2022-05-26 14:41:43 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2018-01-24 17:51:03 +03:00
}
2022-05-26 14:41:43 +03:00
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , true , tmp_ctx , & ads ) ;
2022-05-26 14:41:43 +03:00
if ( ! ADS_ERR_OK ( status ) ) {
goto out ;
2018-01-24 17:51:03 +03:00
}
2022-05-26 14:41:43 +03:00
2018-01-24 17:51:03 +03:00
if ( argc > 1 ) {
ok = ads_setspn_delete ( ads , argv [ 0 ] , argv [ 1 ] ) ;
} else {
ok = ads_setspn_delete ( ads , lp_netbios_name ( ) , argv [ 0 ] ) ;
}
2022-05-26 14:41:43 +03:00
ret = ok ? 0 : - 1 ;
out :
TALLOC_FREE ( tmp_ctx ) ;
2018-01-24 17:51:03 +03:00
return ret ;
}
2018-01-24 17:26:03 +03:00
int net_ads_setspn ( struct net_context * c , int argc , const char * * argv )
{
struct functable func [ ] = {
{
" list " ,
net_ads_setspn_list ,
NET_TRANSPORT_ADS ,
N_ ( " List Service Principal Names (SPN) " ) ,
N_ ( " net ads setspn list machine \n "
" List Service Principal Names (SPN) " )
} ,
2018-01-24 17:41:06 +03:00
{
" add " ,
net_ads_setspn_add ,
NET_TRANSPORT_ADS ,
N_ ( " Add Service Principal Names (SPN) " ) ,
N_ ( " net ads setspn add machine spn \n "
" Add Service Principal Names (SPN) " )
} ,
2018-01-24 17:51:03 +03:00
{
" delete " ,
net_ads_setspn_delete ,
NET_TRANSPORT_ADS ,
N_ ( " Delete Service Principal Names (SPN) " ) ,
N_ ( " net ads setspn delete machine spn \n "
" Delete Service Principal Names (SPN) " )
} ,
2018-01-24 17:26:03 +03:00
{ NULL , NULL , 0 , NULL , NULL }
} ;
return net_run_function ( c , argc , argv , " net ads setspn " , func ) ;
}
2014-09-25 00:16:20 +04:00
static int net_ads_enctype_lookup_account ( struct net_context * c ,
ADS_STRUCT * ads ,
const char * account ,
LDAPMessage * * res ,
const char * * enctype_str )
{
const char * filter ;
const char * attrs [ ] = {
" msDS-SupportedEncryptionTypes " ,
NULL
} ;
int count ;
int ret = - 1 ;
ADS_STATUS status ;
filter = talloc_asprintf ( c , " (&(objectclass=user)(sAMAccountName=%s)) " ,
account ) ;
if ( filter = = NULL ) {
goto done ;
}
status = ads_search ( ads , res , filter , attrs ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( _ ( " no account found with filter: %s \n " ) , filter ) ;
goto done ;
}
count = ads_count_replies ( ads , * res ) ;
switch ( count ) {
case 1 :
break ;
case 0 :
d_printf ( _ ( " no account found with filter: %s \n " ) , filter ) ;
goto done ;
default :
d_printf ( _ ( " multiple accounts found with filter: %s \n " ) , filter ) ;
goto done ;
}
if ( enctype_str ) {
* enctype_str = ads_pull_string ( ads , c , * res ,
" msDS-SupportedEncryptionTypes " ) ;
if ( * enctype_str = = NULL ) {
d_printf ( _ ( " no msDS-SupportedEncryptionTypes attribute found \n " ) ) ;
goto done ;
}
}
ret = 0 ;
done :
return ret ;
}
static void net_ads_enctype_dump_enctypes ( const char * username ,
const char * enctype_str )
{
2014-09-29 18:01:25 +04:00
int enctypes = atoi ( enctype_str ) ;
2014-09-25 00:16:20 +04:00
2014-09-29 18:01:25 +04:00
d_printf ( _ ( " '%s' uses \" msDS-SupportedEncryptionTypes \" : %d (0x%08x) \n " ) ,
username , enctypes , enctypes ) ;
2014-09-25 00:16:20 +04:00
printf ( " [%s] 0x%08x DES-CBC-CRC \n " ,
enctypes & ENC_CRC32 ? " X " : " " ,
ENC_CRC32 ) ;
printf ( " [%s] 0x%08x DES-CBC-MD5 \n " ,
enctypes & ENC_RSA_MD5 ? " X " : " " ,
ENC_RSA_MD5 ) ;
printf ( " [%s] 0x%08x RC4-HMAC \n " ,
enctypes & ENC_RC4_HMAC_MD5 ? " X " : " " ,
ENC_RC4_HMAC_MD5 ) ;
printf ( " [%s] 0x%08x AES128-CTS-HMAC-SHA1-96 \n " ,
enctypes & ENC_HMAC_SHA1_96_AES128 ? " X " : " " ,
ENC_HMAC_SHA1_96_AES128 ) ;
printf ( " [%s] 0x%08x AES256-CTS-HMAC-SHA1-96 \n " ,
enctypes & ENC_HMAC_SHA1_96_AES256 ? " X " : " " ,
ENC_HMAC_SHA1_96_AES256 ) ;
2022-11-22 11:48:45 +03:00
printf ( " [%s] 0x%08x AES256-CTS-HMAC-SHA1-96-SK \n " ,
enctypes & ENC_HMAC_SHA1_96_AES256_SK ? " X " : " " ,
ENC_HMAC_SHA1_96_AES256_SK ) ;
printf ( " [%s] 0x%08x RESOURCE-SID-COMPRESSION-DISABLED \n " ,
enctypes & KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED ? " X " : " " ,
KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED ) ;
2014-09-25 00:16:20 +04:00
}
static int net_ads_enctypes_list ( struct net_context * c , int argc , const char * * argv )
{
2022-05-26 14:44:17 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2014-09-25 00:16:20 +04:00
ADS_STATUS status ;
ADS_STRUCT * ads = NULL ;
LDAPMessage * res = NULL ;
const char * str = NULL ;
2022-05-26 14:44:17 +03:00
int ret = - 1 ;
2014-09-25 00:16:20 +04:00
if ( c - > display_usage | | ( argc < 1 ) ) {
d_printf ( " %s \n "
" net ads enctypes list \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " List supported enctypes " ) ) ;
2022-05-26 14:44:17 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2014-09-25 00:16:20 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2014-09-25 00:16:20 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2022-05-26 14:44:17 +03:00
goto out ;
2014-09-25 00:16:20 +04:00
}
ret = net_ads_enctype_lookup_account ( c , ads , argv [ 0 ] , & res , & str ) ;
if ( ret ) {
2022-05-26 14:44:17 +03:00
goto out ;
2014-09-25 00:16:20 +04:00
}
net_ads_enctype_dump_enctypes ( argv [ 0 ] , str ) ;
ret = 0 ;
2022-05-26 14:44:17 +03:00
out :
2014-09-25 00:16:20 +04:00
ads_msgfree ( ads , res ) ;
2022-05-26 14:44:17 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2014-09-25 00:16:20 +04:00
return ret ;
}
static int net_ads_enctypes_set ( struct net_context * c , int argc , const char * * argv )
{
2022-05-26 14:49:18 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2014-09-25 00:16:20 +04:00
int ret = - 1 ;
ADS_STATUS status ;
2022-05-26 14:49:18 +03:00
ADS_STRUCT * ads = NULL ;
2014-09-25 00:16:20 +04:00
LDAPMessage * res = NULL ;
2022-05-26 14:49:18 +03:00
const char * etype_list_str = NULL ;
const char * dn = NULL ;
ADS_MODLIST mods = NULL ;
2014-09-25 00:16:20 +04:00
uint32_t etype_list ;
2022-05-26 14:49:18 +03:00
const char * str = NULL ;
2014-09-25 00:16:20 +04:00
if ( c - > display_usage | | argc < 1 ) {
d_printf ( " %s \n "
" net ads enctypes set <sAMAccountName> [enctypes] \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Set supported enctypes " ) ) ;
2022-05-26 14:49:18 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2014-09-25 00:16:20 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2014-09-25 00:16:20 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2022-05-26 14:49:18 +03:00
goto done ;
2014-09-25 00:16:20 +04:00
}
ret = net_ads_enctype_lookup_account ( c , ads , argv [ 0 ] , & res , NULL ) ;
if ( ret ) {
goto done ;
}
2022-05-26 14:49:18 +03:00
dn = ads_get_dn ( ads , tmp_ctx , res ) ;
2014-09-25 00:16:20 +04:00
if ( dn = = NULL ) {
goto done ;
}
2022-11-23 17:20:40 +03:00
etype_list = 0 ;
etype_list | = ENC_RC4_HMAC_MD5 ;
2014-09-25 00:16:20 +04:00
etype_list | = ENC_HMAC_SHA1_96_AES128 ;
etype_list | = ENC_HMAC_SHA1_96_AES256 ;
if ( argv [ 1 ] ! = NULL ) {
sscanf ( argv [ 1 ] , " %i " , & etype_list ) ;
}
2022-05-26 14:49:18 +03:00
etype_list_str = talloc_asprintf ( tmp_ctx , " %d " , etype_list ) ;
2014-09-25 00:16:20 +04:00
if ( ! etype_list_str ) {
goto done ;
}
2022-05-26 14:49:18 +03:00
mods = ads_init_mods ( tmp_ctx ) ;
2014-09-25 00:16:20 +04:00
if ( ! mods ) {
goto done ;
}
2022-05-26 14:49:18 +03:00
status = ads_mod_str ( tmp_ctx , & mods , " msDS-SupportedEncryptionTypes " ,
2014-09-25 00:16:20 +04:00
etype_list_str ) ;
if ( ! ADS_ERR_OK ( status ) ) {
goto done ;
}
status = ads_gen_mod ( ads , dn , mods ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( _ ( " failed to add msDS-SupportedEncryptionTypes: %s \n " ) ,
ads_errstr ( status ) ) ;
goto done ;
}
ads_msgfree ( ads , res ) ;
2022-05-26 14:49:18 +03:00
res = NULL ;
2014-09-25 00:16:20 +04:00
ret = net_ads_enctype_lookup_account ( c , ads , argv [ 0 ] , & res , & str ) ;
if ( ret ) {
goto done ;
}
net_ads_enctype_dump_enctypes ( argv [ 0 ] , str ) ;
ret = 0 ;
done :
ads_msgfree ( ads , res ) ;
2022-05-26 14:49:18 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2014-09-25 00:16:20 +04:00
return ret ;
}
static int net_ads_enctypes_delete ( struct net_context * c , int argc , const char * * argv )
{
2022-05-26 14:51:44 +03:00
TALLOC_CTX * tmp_ctx = talloc_stackframe ( ) ;
2014-09-25 00:16:20 +04:00
int ret = - 1 ;
ADS_STATUS status ;
2022-05-26 14:51:44 +03:00
ADS_STRUCT * ads = NULL ;
2014-09-25 00:16:20 +04:00
LDAPMessage * res = NULL ;
2022-05-26 14:51:44 +03:00
const char * dn = NULL ;
ADS_MODLIST mods = NULL ;
2014-09-25 00:16:20 +04:00
if ( c - > display_usage | | argc < 1 ) {
d_printf ( " %s \n "
" net ads enctypes delete <sAMAccountName> \n "
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Delete supported enctypes " ) ) ;
2022-05-26 14:51:44 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-06-21 14:49:08 +03:00
return - 1 ;
2014-09-25 00:16:20 +04:00
}
2022-05-26 15:41:24 +03:00
status = ads_startup ( c , false , tmp_ctx , & ads ) ;
2014-09-25 00:16:20 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
2022-05-26 14:51:44 +03:00
goto done ;
2014-09-25 00:16:20 +04:00
}
ret = net_ads_enctype_lookup_account ( c , ads , argv [ 0 ] , & res , NULL ) ;
if ( ret ) {
goto done ;
}
2022-05-26 14:51:44 +03:00
dn = ads_get_dn ( ads , tmp_ctx , res ) ;
2014-09-25 00:16:20 +04:00
if ( dn = = NULL ) {
goto done ;
}
2022-05-26 14:51:44 +03:00
mods = ads_init_mods ( tmp_ctx ) ;
2014-09-25 00:16:20 +04:00
if ( ! mods ) {
goto done ;
}
2022-05-26 14:51:44 +03:00
status = ads_mod_str ( tmp_ctx , & mods , " msDS-SupportedEncryptionTypes " , NULL ) ;
2014-09-25 00:16:20 +04:00
if ( ! ADS_ERR_OK ( status ) ) {
goto done ;
}
status = ads_gen_mod ( ads , dn , mods ) ;
if ( ! ADS_ERR_OK ( status ) ) {
d_printf ( _ ( " failed to remove msDS-SupportedEncryptionTypes: %s \n " ) ,
ads_errstr ( status ) ) ;
goto done ;
}
ret = 0 ;
done :
ads_msgfree ( ads , res ) ;
2022-05-26 14:51:44 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2014-09-25 00:16:20 +04:00
return ret ;
}
static int net_ads_enctypes ( struct net_context * c , int argc , const char * * argv )
{
struct functable func [ ] = {
{
" list " ,
net_ads_enctypes_list ,
NET_TRANSPORT_ADS ,
N_ ( " List the supported encryption types " ) ,
N_ ( " net ads enctypes list \n "
" List the supported encryption types " )
} ,
{
" set " ,
net_ads_enctypes_set ,
NET_TRANSPORT_ADS ,
N_ ( " Set the supported encryption types " ) ,
N_ ( " net ads enctypes set \n "
" Set the supported encryption types " )
} ,
{
" delete " ,
net_ads_enctypes_delete ,
NET_TRANSPORT_ADS ,
N_ ( " Delete the supported encryption types " ) ,
N_ ( " net ads enctypes delete \n "
" Delete the supported encryption types " )
} ,
{ NULL , NULL , 0 , NULL , NULL }
} ;
return net_run_function ( c , argc , argv , " net ads enctypes " , func ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads ( struct net_context * c , int argc , const char * * argv )
2001-11-25 03:18:11 +03:00
{
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-20 15:35:04 +04:00
{
" info " ,
net_ads_info ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Display details on remote ADS server " ) ,
N_ ( " net ads info \n "
" Display details on remote ADS server " )
2008-05-20 15:35:04 +04:00
} ,
{
" join " ,
net_ads_join ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Join the local machine to ADS realm " ) ,
N_ ( " net ads join \n "
" Join the local machine to ADS realm " )
2008-05-20 15:35:04 +04:00
} ,
{
" testjoin " ,
net_ads_testjoin ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Validate machine account " ) ,
N_ ( " net ads testjoin \n "
" Validate machine account " )
2008-05-20 15:35:04 +04:00
} ,
{
" leave " ,
net_ads_leave ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Remove the local machine from ADS " ) ,
N_ ( " net ads leave \n "
" Remove the local machine from ADS " )
2008-05-20 15:35:04 +04:00
} ,
{
" status " ,
net_ads_status ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Display machine account details " ) ,
N_ ( " net ads status \n "
" Display machine account details " )
2008-05-20 15:35:04 +04:00
} ,
{
" user " ,
net_ads_user ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " List/modify users " ) ,
N_ ( " net ads user \n "
" List/modify users " )
2008-05-20 15:35:04 +04:00
} ,
{
" group " ,
net_ads_group ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " List/modify groups " ) ,
N_ ( " net ads group \n "
" List/modify groups " )
2008-05-20 15:35:04 +04:00
} ,
{
" dns " ,
net_ads_dns ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Issue dynamic DNS update " ) ,
N_ ( " net ads dns \n "
" Issue dynamic DNS update " )
2008-05-20 15:35:04 +04:00
} ,
{
" password " ,
net_ads_password ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Change user passwords " ) ,
N_ ( " net ads password \n "
" Change user passwords " )
2008-05-20 15:35:04 +04:00
} ,
{
" changetrustpw " ,
net_ads_changetrustpw ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Change trust account password " ) ,
N_ ( " net ads changetrustpw \n "
" Change trust account password " )
2008-05-20 15:35:04 +04:00
} ,
{
" printer " ,
net_ads_printer ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " List/modify printer entries " ) ,
N_ ( " net ads printer \n "
" List/modify printer entries " )
2008-05-20 15:35:04 +04:00
} ,
{
" search " ,
net_ads_search ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Issue LDAP search using filter " ) ,
N_ ( " net ads search \n "
" Issue LDAP search using filter " )
2008-05-20 15:35:04 +04:00
} ,
{
" dn " ,
net_ads_dn ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Issue LDAP search by DN " ) ,
N_ ( " net ads dn \n "
" Issue LDAP search by DN " )
2008-05-20 15:35:04 +04:00
} ,
{
" sid " ,
net_ads_sid ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Issue LDAP search by SID " ) ,
N_ ( " net ads sid \n "
" Issue LDAP search by SID " )
2008-05-20 15:35:04 +04:00
} ,
{
" workgroup " ,
net_ads_workgroup ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Display workgroup name " ) ,
N_ ( " net ads workgroup \n "
" Display the workgroup name " )
2008-05-20 15:35:04 +04:00
} ,
{
" lookup " ,
net_ads_lookup ,
NET_TRANSPORT_ADS ,
2017-02-17 22:53:39 +03:00
N_ ( " Perform CLDAP query on DC " ) ,
2009-07-30 01:28:01 +04:00
N_ ( " net ads lookup \n "
" Find the ADS DC using CLDAP lookups " )
2008-05-20 15:35:04 +04:00
} ,
{
" keytab " ,
net_ads_keytab ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Manage local keytab file " ) ,
N_ ( " net ads keytab \n "
" Manage local keytab file " )
2008-05-20 15:35:04 +04:00
} ,
2018-01-24 17:26:03 +03:00
{
" setspn " ,
net_ads_setspn ,
NET_TRANSPORT_ADS ,
N_ ( " Manage Service Principal Names (SPN)s " ) ,
N_ ( " net ads spnset \n "
" Manage Service Principal Names (SPN)s " )
} ,
2008-05-20 15:35:04 +04:00
{
" gpo " ,
net_ads_gpo ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Manage group policy objects " ) ,
N_ ( " net ads gpo \n "
" Manage group policy objects " )
2008-05-20 15:35:04 +04:00
} ,
{
" kerberos " ,
net_ads_kerberos ,
NET_TRANSPORT_ADS ,
2009-07-30 01:28:01 +04:00
N_ ( " Manage kerberos keytab " ) ,
N_ ( " net ads kerberos \n "
" Manage kerberos keytab " )
2008-05-20 15:35:04 +04:00
} ,
2014-09-25 00:16:20 +04:00
{
" enctypes " ,
net_ads_enctypes ,
NET_TRANSPORT_ADS ,
N_ ( " List/modify supported encryption types " ) ,
N_ ( " net ads enctypes \n "
" List/modify enctypes " )
} ,
2008-05-20 15:35:04 +04:00
{ NULL , NULL , 0 , NULL , NULL }
2001-11-25 03:18:11 +03:00
} ;
2007-09-18 01:04:10 +04:00
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net ads " , func ) ;
2001-11-25 03:18:11 +03:00
}
# else
2004-06-24 23:25:20 +04:00
static int net_ads_noads ( void )
2001-11-25 03:18:11 +03:00
{
2009-07-30 01:28:01 +04:00
d_fprintf ( stderr , _ ( " ADS support not compiled in \n " ) ) ;
2001-11-25 03:18:11 +03:00
return - 1 ;
}
2008-05-10 01:22:12 +04:00
int net_ads_keytab ( struct net_context * c , int argc , const char * * argv )
2004-06-23 01:58:35 +04:00
{
return net_ads_noads ( ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads_kerberos ( struct net_context * c , int argc , const char * * argv )
2007-07-19 17:47:53 +04:00
{
return net_ads_noads ( ) ;
}
2018-01-24 17:26:03 +03:00
int net_ads_setspn ( struct net_context * c , int argc , const char * * argv )
{
return net_ads_noads ( ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads_changetrustpw ( struct net_context * c , int argc , const char * * argv )
2003-04-15 02:27:09 +04:00
{
return net_ads_noads ( ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads_join ( struct net_context * c , int argc , const char * * argv )
2002-04-04 20:47:24 +04:00
{
return net_ads_noads ( ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads_user ( struct net_context * c , int argc , const char * * argv )
2002-04-04 20:47:24 +04:00
{
return net_ads_noads ( ) ;
}
2008-05-10 01:22:12 +04:00
int net_ads_group ( struct net_context * c , int argc , const char * * argv )
2002-07-15 14:35:28 +04:00
{
return net_ads_noads ( ) ;
}
2010-05-21 20:06:51 +04:00
int net_ads_gpo ( struct net_context * c , int argc , const char * * argv )
2009-09-03 00:04:03 +04:00
{
return net_ads_noads ( ) ;
}
2002-04-04 20:47:24 +04:00
/* this one shouldn't display a message */
2008-05-10 01:22:12 +04:00
int net_ads_check ( struct net_context * c )
2002-03-16 04:30:09 +03:00
{
return - 1 ;
}
2008-05-10 01:22:12 +04:00
int net_ads_check_our_domain ( struct net_context * c )
2006-07-17 15:04:47 +04:00
{
return - 1 ;
}
2008-05-10 01:22:12 +04:00
int net_ads ( struct net_context * c , int argc , const char * * argv )
2001-11-25 03:18:11 +03:00
{
2008-06-12 13:50:09 +04:00
return net_ads_noads ( ) ;
2001-11-25 03:18:11 +03:00
}
2011-04-15 14:37:55 +04:00
# endif /* HAVE_ADS */