mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
added "net join" command
this completes the first stage of the smbd ADS support
(This used to be commit 058a5aee90
)
This commit is contained in:
@ -115,6 +115,23 @@ Here are some other suggestions:
|
|||||||
comment start / ** so that they can be picked up by Doxygen, as in
|
comment start / ** so that they can be picked up by Doxygen, as in
|
||||||
this file.
|
this file.
|
||||||
|
|
||||||
|
23) Keep the scope narrow. This means making functions/variables
|
||||||
|
static whenever possible. We don't want our namespace
|
||||||
|
polluted. Each module should have a minimal number of externally
|
||||||
|
visible functions or variables.
|
||||||
|
|
||||||
|
24) Use function pointers to keep knowledge about particular pieces of
|
||||||
|
code isolated in one place. We don't want a particular piece of
|
||||||
|
functionality to be spread out across lots of places - that makes
|
||||||
|
for fragile, hand to maintain code. Instead, design an interface
|
||||||
|
and use tables containing function pointers to implement specific
|
||||||
|
functionality. This is particularly important for command
|
||||||
|
interpreters.
|
||||||
|
|
||||||
|
25) Think carefully about what it will be like for someone else to add
|
||||||
|
to and maintain your code. If it would be hard for someone else to
|
||||||
|
maintain then do it another way.
|
||||||
|
|
||||||
The suggestions above are simply that, suggestions, but the information may
|
The suggestions above are simply that, suggestions, but the information may
|
||||||
help in reducing the routine rework done on new code. The preceeding list
|
help in reducing the routine rework done on new code. The preceeding list
|
||||||
is expected to change routinely as new support routines and macros are
|
is expected to change routinely as new support routines and macros are
|
||||||
|
@ -131,7 +131,7 @@ UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
|
|||||||
|
|
||||||
PARAM_OBJ = param/loadparm.o param/params.o dynconfig.o
|
PARAM_OBJ = param/loadparm.o param/params.o dynconfig.o
|
||||||
|
|
||||||
LIBADS_OBJ = libads/ldap.o
|
LIBADS_OBJ = libads/ldap.o libads/krb5_setpw.o libads/kerberos.o passdb/secrets.o
|
||||||
|
|
||||||
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
|
LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \
|
||||||
libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \
|
libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \
|
||||||
@ -179,7 +179,7 @@ RPC_CLIENT_OBJ = rpc_client/cli_netlogon.o rpc_client/cli_pipe.o \
|
|||||||
|
|
||||||
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
|
LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
|
||||||
|
|
||||||
PASSDB_OBJ = passdb/passdb.o passdb/secrets.o \
|
PASSDB_OBJ = passdb/passdb.o \
|
||||||
passdb/machine_sid.o passdb/pdb_smbpasswd.o \
|
passdb/machine_sid.o passdb/pdb_smbpasswd.o \
|
||||||
passdb/pdb_tdb.o passdb/pdb_ldap.o \
|
passdb/pdb_tdb.o passdb/pdb_ldap.o \
|
||||||
passdb/pdb_nisplus.o
|
passdb/pdb_nisplus.o
|
||||||
@ -319,8 +319,8 @@ CLIENT_OBJ = client/client.o client/clitar.o \
|
|||||||
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
|
$(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
|
||||||
$(READLINE_OBJ)
|
$(READLINE_OBJ)
|
||||||
|
|
||||||
NET_OBJ = utils/net.o $(LIBSMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
|
NET_OBJ = utils/net.o utils/net_join.o \
|
||||||
@BUILD_POPT@
|
$(LIBSMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) @BUILD_POPT@
|
||||||
|
|
||||||
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
|
CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
|
|||||||
|
|
||||||
PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
|
PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
|
||||||
$(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ) $(RPCCLIENT_OBJ1) \
|
$(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ) $(RPCCLIENT_OBJ1) \
|
||||||
$(LIBMSRPC_OBJ) $(RPC_CLIENT_OBJ) $(AUTH_OBJ)
|
$(LIBMSRPC_OBJ) $(RPC_CLIENT_OBJ) $(AUTH_OBJ) $(NET_OBJ)
|
||||||
|
|
||||||
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
|
NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
|
||||||
NSS_OBJ = $(NSS_OBJ_0:.o=.po)
|
NSS_OBJ = $(NSS_OBJ_0:.o=.po)
|
||||||
|
@ -2159,7 +2159,7 @@ struct cli_state *do_connect(const char *server, const char *share)
|
|||||||
password, strlen(password),
|
password, strlen(password),
|
||||||
workgroup)) {
|
workgroup)) {
|
||||||
/* if a password was not supplied then try again with a null username */
|
/* if a password was not supplied then try again with a null username */
|
||||||
if (password[0] || !username[0] ||
|
if (password[0] || !username[0] || use_kerberos ||
|
||||||
!cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
|
!cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
|
||||||
d_printf("session setup failed: %s\n", cli_errstr(c));
|
d_printf("session setup failed: %s\n", cli_errstr(c));
|
||||||
cli_shutdown(c);
|
cli_shutdown(c);
|
||||||
|
@ -233,7 +233,7 @@ add a privilege to a privilege array
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
BOOL add_privilege(uint32 *privilege, uint32 priv)
|
BOOL add_privilege(uint32 *privilege, uint32 priv)
|
||||||
{
|
{
|
||||||
int i;
|
int i=0;
|
||||||
|
|
||||||
while (i<PRIV_ALL_INDEX && privilege[i]!=0 && privilege[i]!=priv)
|
while (i<PRIV_ALL_INDEX && privilege[i]!=0 && privilege[i]!=priv)
|
||||||
i++;
|
i++;
|
||||||
@ -262,6 +262,7 @@ BOOL add_all_privilege(uint32 *privilege)
|
|||||||
add_privilege(privilege, SE_PRIV_ADD_USERS);
|
add_privilege(privilege, SE_PRIV_ADD_USERS);
|
||||||
add_privilege(privilege, SE_PRIV_ADD_MACHINES);
|
add_privilege(privilege, SE_PRIV_ADD_MACHINES);
|
||||||
add_privilege(privilege, SE_PRIV_PRINT_OPERATOR);
|
add_privilege(privilege, SE_PRIV_PRINT_OPERATOR);
|
||||||
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -301,7 +302,6 @@ BOOL default_group_mapping(void)
|
|||||||
fstring str_admins;
|
fstring str_admins;
|
||||||
fstring str_users;
|
fstring str_users;
|
||||||
fstring str_guests;
|
fstring str_guests;
|
||||||
int i;
|
|
||||||
|
|
||||||
uint32 privilege_none[PRIV_ALL_INDEX];
|
uint32 privilege_none[PRIV_ALL_INDEX];
|
||||||
uint32 privilege_all[PRIV_ALL_INDEX];
|
uint32 privilege_all[PRIV_ALL_INDEX];
|
||||||
|
@ -737,6 +737,13 @@ typedef struct smb_wpasswd {
|
|||||||
wpstring pw_shell;
|
wpstring pw_shell;
|
||||||
} SMB_STRUCT_WPASSWD;
|
} SMB_STRUCT_WPASSWD;
|
||||||
|
|
||||||
|
/* used in net.c */
|
||||||
|
struct functable {
|
||||||
|
char *funcname;
|
||||||
|
int (*fn)();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Defines for wisXXX functions. */
|
/* Defines for wisXXX functions. */
|
||||||
#define UNI_UPPER 0x1
|
#define UNI_UPPER 0x1
|
||||||
#define UNI_LOWER 0x2
|
#define UNI_LOWER 0x2
|
||||||
|
@ -22,7 +22,13 @@
|
|||||||
#ifndef _SECRETS_H
|
#ifndef _SECRETS_H
|
||||||
#define _SECRETS_H
|
#define _SECRETS_H
|
||||||
|
|
||||||
|
/* the first one is for the hashed password (NT4 style) the latter
|
||||||
|
for plaintext (ADS
|
||||||
|
*/
|
||||||
#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
|
#define SECRETS_MACHINE_ACCT_PASS "SECRETS/$MACHINE.ACC"
|
||||||
|
#define SECRETS_MACHINE_PASSWORD "SECRETS/MACHINE_PASSWORD"
|
||||||
|
|
||||||
|
|
||||||
#define SECRETS_DOMAIN_SID "SECRETS/SID"
|
#define SECRETS_DOMAIN_SID "SECRETS/SID"
|
||||||
#define SECRETS_SAM_SID "SAM/SID"
|
#define SECRETS_SAM_SID "SAM/SID"
|
||||||
|
|
||||||
|
@ -905,6 +905,37 @@ connect_again:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
open a connected UDP socket to host on port
|
||||||
|
*/
|
||||||
|
int open_udp_socket(const char *host, int port)
|
||||||
|
{
|
||||||
|
int type = SOCK_DGRAM;
|
||||||
|
struct sockaddr_in sock_out;
|
||||||
|
int res;
|
||||||
|
struct in_addr *addr;
|
||||||
|
|
||||||
|
addr = interpret_addr2(host);
|
||||||
|
|
||||||
|
res = socket(PF_INET, type, 0);
|
||||||
|
if (res == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset((char *)&sock_out,'\0',sizeof(sock_out));
|
||||||
|
putip((char *)&sock_out.sin_addr,(char *)addr);
|
||||||
|
sock_out.sin_port = htons(port);
|
||||||
|
sock_out.sin_family = PF_INET;
|
||||||
|
|
||||||
|
if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
|
||||||
|
close(res);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the following 3 client_*() functions are nasty ways of allowing
|
/* the following 3 client_*() functions are nasty ways of allowing
|
||||||
some generic functions to get info that really should be hidden in
|
some generic functions to get info that really should be hidden in
|
||||||
particular modules */
|
particular modules */
|
||||||
|
149
source3/libads/kerberos.c
Normal file
149
source3/libads/kerberos.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/Netbios implementation.
|
||||||
|
Version 3.0
|
||||||
|
kerberos utility library
|
||||||
|
Copyright (C) Andrew Tridgell 2001
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_KRB5
|
||||||
|
|
||||||
|
/*
|
||||||
|
verify an incoming ticket and parse out the principal name and
|
||||||
|
authorization_data if available
|
||||||
|
*/
|
||||||
|
NTSTATUS ads_verify_ticket(const DATA_BLOB *ticket,
|
||||||
|
char **principal, DATA_BLOB *auth_data)
|
||||||
|
{
|
||||||
|
krb5_context context;
|
||||||
|
krb5_auth_context auth_context = NULL;
|
||||||
|
krb5_keytab keytab = NULL;
|
||||||
|
krb5_data packet;
|
||||||
|
krb5_ticket *tkt = NULL;
|
||||||
|
krb5_data salt;
|
||||||
|
krb5_encrypt_block eblock;
|
||||||
|
int ret;
|
||||||
|
krb5_keyblock * key;
|
||||||
|
krb5_principal host_princ;
|
||||||
|
char *host_princ_s;
|
||||||
|
extern pstring global_myname;
|
||||||
|
fstring myname;
|
||||||
|
char *password_s;
|
||||||
|
krb5_data password;
|
||||||
|
|
||||||
|
if (!secrets_init()) {
|
||||||
|
DEBUG(1,("secrets_init failed\n"));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
password_s = secrets_fetch_machine_password();
|
||||||
|
if (!password_s) {
|
||||||
|
DEBUG(1,("failed to fetch machine password\n"));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
password.data = password_s;
|
||||||
|
password.length = strlen(password_s);
|
||||||
|
|
||||||
|
ret = krb5_init_context(&context);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_set_default_realm(context, lp_realm());
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_set_default_realm failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this whole process is far more complex than I would
|
||||||
|
like. We have to go through all this to allow us to store
|
||||||
|
the secret internally, instead of using /etc/krb5.keytab */
|
||||||
|
ret = krb5_auth_con_init(context, &auth_context);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_auth_con_init failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fstrcpy(myname, global_myname);
|
||||||
|
strlower(myname);
|
||||||
|
asprintf(&host_princ_s, "HOST/%s@%s", myname, lp_realm());
|
||||||
|
ret = krb5_parse_name(context, host_princ_s, &host_princ);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", host_princ_s, error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_principal2salt(context, host_princ, &salt);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(key = (krb5_keyblock *)malloc(sizeof(*key)))) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5);
|
||||||
|
|
||||||
|
ret = krb5_string_to_key(context, &eblock, key, &password, &salt);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_string_to_key failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_auth_con_setuseruserkey(context, auth_context, key);
|
||||||
|
|
||||||
|
packet.length = ticket->length;
|
||||||
|
packet.data = (krb5_pointer)ticket->data;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
file_save("/tmp/ticket.dat", ticket->data, ticket->length);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ret = krb5_rd_req(context, &auth_context, &packet,
|
||||||
|
NULL, keytab, NULL, &tkt))) {
|
||||||
|
DEBUG(3,("krb5_rd_req with auth failed (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tkt->enc_part2) {
|
||||||
|
*auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents,
|
||||||
|
tkt->enc_part2->authorization_data[0]->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (tkt->enc_part2) {
|
||||||
|
file_save("/tmp/authdata.dat",
|
||||||
|
tkt->enc_part2->authorization_data[0]->contents,
|
||||||
|
tkt->enc_part2->authorization_data[0]->length);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, principal))) {
|
||||||
|
DEBUG(3,("krb5_unparse_name failed (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
352
source3/libads/krb5_setpw.c
Normal file
352
source3/libads/krb5_setpw.c
Normal file
@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/Netbios implementation.
|
||||||
|
Version 3.0
|
||||||
|
krb5 set password implementation
|
||||||
|
Copyright (C) Andrew Tridgell 2001
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#if HAVE_KRB5
|
||||||
|
|
||||||
|
#define DEFAULT_KPASSWD_PORT 464
|
||||||
|
#define KRB5_KPASSWD_VERS_CHANGEPW 1
|
||||||
|
#define KRB5_KPASSWD_VERS_SETPW 0xff80
|
||||||
|
#define KRB5_KPASSWD_ACCESSDENIED 5
|
||||||
|
#define KRB5_KPASSWD_BAD_VERSION 6
|
||||||
|
|
||||||
|
/* This implements the Kerb password change protocol as specifed in
|
||||||
|
* kerb-chg-password-02.txt
|
||||||
|
*/
|
||||||
|
static DATA_BLOB encode_krb5_setpw(const char *hostname,
|
||||||
|
const char *realm, const char *password)
|
||||||
|
{
|
||||||
|
ASN1_DATA req;
|
||||||
|
DATA_BLOB ret;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
|
||||||
|
asn1_push_tag(&req, ASN1_SEQUENCE(0));
|
||||||
|
asn1_push_tag(&req, ASN1_CONTEXT(0));
|
||||||
|
asn1_write_OctetString(&req, password, strlen(password));
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
|
||||||
|
asn1_push_tag(&req, ASN1_CONTEXT(1));
|
||||||
|
asn1_push_tag(&req, ASN1_SEQUENCE(0));
|
||||||
|
|
||||||
|
asn1_push_tag(&req, ASN1_CONTEXT(0));
|
||||||
|
asn1_write_Integer(&req, 1);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
|
||||||
|
asn1_push_tag(&req, ASN1_CONTEXT(1));
|
||||||
|
asn1_push_tag(&req, ASN1_SEQUENCE(0));
|
||||||
|
asn1_write_GeneralString(&req, "HOST");
|
||||||
|
asn1_write_GeneralString(&req, hostname);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
|
||||||
|
asn1_push_tag(&req, ASN1_CONTEXT(2));
|
||||||
|
asn1_write_GeneralString(&req, realm);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
asn1_pop_tag(&req);
|
||||||
|
|
||||||
|
ret = data_blob(req.data, req.length);
|
||||||
|
asn1_free(&req);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code build_setpw_request(krb5_context context,
|
||||||
|
krb5_auth_context auth_context,
|
||||||
|
krb5_data *ap_req,
|
||||||
|
const char *hostname,
|
||||||
|
const char *realm,
|
||||||
|
const char *passwd,
|
||||||
|
krb5_data *packet)
|
||||||
|
{
|
||||||
|
krb5_error_code ret;
|
||||||
|
krb5_data cipherpw;
|
||||||
|
krb5_data encoded_setpw;
|
||||||
|
krb5_replay_data replay;
|
||||||
|
char *p;
|
||||||
|
DATA_BLOB setpw;
|
||||||
|
|
||||||
|
ret = krb5_auth_con_setflags(context,
|
||||||
|
auth_context,KRB5_AUTH_CONTEXT_DO_SEQUENCE);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_auth_con_setflags failed (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
setpw = encode_krb5_setpw(hostname, realm, passwd);
|
||||||
|
|
||||||
|
encoded_setpw.data = setpw.data;
|
||||||
|
encoded_setpw.length = setpw.length;
|
||||||
|
|
||||||
|
ret = krb5_mk_priv(context, auth_context,
|
||||||
|
&encoded_setpw, &cipherpw, &replay);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_mk_priv failed (%s)\n", error_message(ret)));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet->data = (char *)malloc(ap_req->length + cipherpw.length + 6);
|
||||||
|
|
||||||
|
/* see the RFC for details */
|
||||||
|
p = packet->data + 2;
|
||||||
|
RSSVAL(p, 0, 0xff80); p += 2;
|
||||||
|
RSSVAL(p, 0, ap_req->length); p += 2;
|
||||||
|
memcpy(p, ap_req->data, ap_req->length); p += ap_req->length;
|
||||||
|
memcpy(p, cipherpw.data, cipherpw.length); p += cipherpw.length;
|
||||||
|
packet->length = PTR_DIFF(p,packet->data);
|
||||||
|
RSSVAL(packet->data, 0, packet->length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code parse_setpw_reply(krb5_context context,
|
||||||
|
krb5_auth_context auth_context,
|
||||||
|
krb5_data *packet)
|
||||||
|
{
|
||||||
|
krb5_data ap_rep;
|
||||||
|
char *p;
|
||||||
|
int vnum, ret, res_code;
|
||||||
|
krb5_data cipherresult;
|
||||||
|
krb5_data clearresult;
|
||||||
|
krb5_ap_rep_enc_part *ap_rep_enc;
|
||||||
|
krb5_replay_data replay;
|
||||||
|
|
||||||
|
if (packet->length < 4) {
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = packet->data;
|
||||||
|
|
||||||
|
if (packet->data[0] == 0x7e || packet->data[0] == 0x5e) {
|
||||||
|
/* it's an error packet. We should parse it ... */
|
||||||
|
DEBUG(1,("Got error packet 0x%x from kpasswd server\n",
|
||||||
|
packet->data[0]));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RSVAL(p, 0) != packet->length) {
|
||||||
|
DEBUG(1,("Bad packet length (%d/%d) from kpasswd server\n",
|
||||||
|
RSVAL(p, 0), packet->length));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
vnum = RSVAL(p, 0); p += 2;
|
||||||
|
|
||||||
|
if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) {
|
||||||
|
DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum));
|
||||||
|
return KRB5KDC_ERR_BAD_PVNO;
|
||||||
|
}
|
||||||
|
|
||||||
|
ap_rep.length = RSVAL(p, 0); p += 2;
|
||||||
|
|
||||||
|
if (p + ap_rep.length >= packet->data + packet->length) {
|
||||||
|
DEBUG(1,("ptr beyond end of packet from kpasswd server\n"));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_rep.length == 0) {
|
||||||
|
DEBUG(1,("got unencrypted setpw result?!\n"));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verify ap_rep */
|
||||||
|
ap_rep.data = p;
|
||||||
|
p += ap_rep.length;
|
||||||
|
|
||||||
|
ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("failed to rd setpw reply (%s)\n", error_message(ret)));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
krb5_free_ap_rep_enc_part(context, ap_rep_enc);
|
||||||
|
|
||||||
|
cipherresult.data = p;
|
||||||
|
cipherresult.length = (packet->data + packet->length) - p;
|
||||||
|
|
||||||
|
ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
|
||||||
|
&replay);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("failed to decrypt setpw reply (%s)\n", error_message(ret)));
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clearresult.length < 2) {
|
||||||
|
ret = KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = clearresult.data;
|
||||||
|
|
||||||
|
res_code = RSVAL(p, 0);
|
||||||
|
|
||||||
|
if ((res_code < KRB5_KPASSWD_SUCCESS) ||
|
||||||
|
(res_code > KRB5_KPASSWD_ACCESSDENIED)) {
|
||||||
|
return KRB5KRB_AP_ERR_MODIFIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS krb5_set_password(const char *kdc_host, const char *hostname,
|
||||||
|
const char *realm, const char *newpw)
|
||||||
|
{
|
||||||
|
krb5_context context;
|
||||||
|
krb5_auth_context auth_context = NULL;
|
||||||
|
krb5_principal principal;
|
||||||
|
char *princ_name;
|
||||||
|
krb5_creds creds, *credsp;
|
||||||
|
krb5_ccache ccache;
|
||||||
|
krb5_data ap_req, chpw_req, chpw_rep;
|
||||||
|
int ret, sock, addr_len;
|
||||||
|
struct sockaddr remote_addr, local_addr;
|
||||||
|
krb5_address local_kaddr, remote_kaddr;
|
||||||
|
|
||||||
|
ret = krb5_init_context(&context);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_cc_default(context, &ccache);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZERO_STRUCT(creds);
|
||||||
|
|
||||||
|
asprintf(&princ_name, "kadmin/changepw@%s", realm);
|
||||||
|
ret = krb5_parse_name(context, princ_name, &creds.server);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
free(princ_name);
|
||||||
|
|
||||||
|
asprintf(&princ_name, "HOST/%s@%s", hostname, realm);
|
||||||
|
ret = krb5_parse_name(context, princ_name, &principal);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
free(princ_name);
|
||||||
|
|
||||||
|
krb5_princ_set_realm(context, creds.server,
|
||||||
|
krb5_princ_realm(context, principal));
|
||||||
|
|
||||||
|
ret = krb5_cc_get_principal(context, ccache, &creds.client);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("Failed to get principal from ccache (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
|
||||||
|
NULL, credsp, &ap_req);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sock = open_udp_socket(kdc_host, DEFAULT_KPASSWD_PORT);
|
||||||
|
if (sock == -1) {
|
||||||
|
DEBUG(1,("failed to open kpasswd socket to %s (%s)\n",
|
||||||
|
kdc_host, strerror(errno)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
addr_len = sizeof(remote_addr);
|
||||||
|
getpeername(sock, &remote_addr, &addr_len);
|
||||||
|
addr_len = sizeof(local_addr);
|
||||||
|
getsockname(sock, &local_addr, &addr_len);
|
||||||
|
|
||||||
|
remote_kaddr.addrtype = ADDRTYPE_INET;
|
||||||
|
remote_kaddr.length = sizeof(((struct sockaddr_in *)&remote_addr)->sin_addr);
|
||||||
|
remote_kaddr.contents = (char *)&(((struct sockaddr_in *)&remote_addr)->sin_addr);
|
||||||
|
local_kaddr.addrtype = ADDRTYPE_INET;
|
||||||
|
local_kaddr.length = sizeof(((struct sockaddr_in *)&local_addr)->sin_addr);
|
||||||
|
local_kaddr.contents = (char *)&(((struct sockaddr_in *)&local_addr)->sin_addr);
|
||||||
|
|
||||||
|
ret = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = build_setpw_request(context, auth_context, &ap_req,
|
||||||
|
hostname, realm, newpw, &chpw_req);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write(sock, chpw_req.data, chpw_req.length) != chpw_req.length) {
|
||||||
|
DEBUG(1,("send of chpw failed (%s)\n", strerror(errno)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(chpw_req.data);
|
||||||
|
|
||||||
|
chpw_rep.length = 1500;
|
||||||
|
chpw_rep.data = (char *) malloc(chpw_rep.length);
|
||||||
|
|
||||||
|
ret = read(sock, chpw_rep.data, chpw_rep.length);
|
||||||
|
if (ret < 0) {
|
||||||
|
DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sock);
|
||||||
|
chpw_rep.length = ret;
|
||||||
|
|
||||||
|
ret = krb5_auth_con_setaddrs(context, auth_context, NULL,&remote_kaddr);
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = parse_setpw_reply(context, auth_context, &chpw_rep);
|
||||||
|
free(chpw_rep.data);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
DEBUG(1,("parse_setpw_reply failed (%s)\n",
|
||||||
|
error_message(ret)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -44,7 +44,7 @@ static char *ads_build_dn(const char *realm)
|
|||||||
|
|
||||||
len = (numdots+1)*4 + strlen(r) + 1;
|
len = (numdots+1)*4 + strlen(r) + 1;
|
||||||
|
|
||||||
ret = malloc(len);
|
ret = malloc(len);
|
||||||
strlcpy(ret,"dc=", len);
|
strlcpy(ret,"dc=", len);
|
||||||
p=strtok(r,".");
|
p=strtok(r,".");
|
||||||
strlcat(ret, p, len);
|
strlcat(ret, p, len);
|
||||||
@ -67,6 +67,25 @@ char *ads_errstr(int rc)
|
|||||||
return ldap_err2string(rc);
|
return ldap_err2string(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
find the ldap server from DNS
|
||||||
|
this won't work till we add a DNS packet parser. Talk about a
|
||||||
|
lousy resolv interface!
|
||||||
|
*/
|
||||||
|
static char *find_ldap_server(ADS_STRUCT *ads)
|
||||||
|
{
|
||||||
|
char *list = NULL;
|
||||||
|
|
||||||
|
if (ldap_domain2hostlist(ads->realm, &list) == LDAP_SUCCESS) {
|
||||||
|
char *p;
|
||||||
|
p = strchr(list, ':');
|
||||||
|
if (p) *p = 0;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
initialise a ADS_STRUCT, ready for some ads_ ops
|
initialise a ADS_STRUCT, ready for some ads_ ops
|
||||||
*/
|
*/
|
||||||
@ -76,7 +95,8 @@ ADS_STRUCT *ads_init(const char *realm,
|
|||||||
{
|
{
|
||||||
ADS_STRUCT *ads;
|
ADS_STRUCT *ads;
|
||||||
|
|
||||||
ads = (ADS_STRUCT *)xmalloc(sizeof(*ads));
|
ads = (ADS_STRUCT *)malloc(sizeof(*ads));
|
||||||
|
if (!ads) return NULL;
|
||||||
memset(ads, 0, sizeof(*ads));
|
memset(ads, 0, sizeof(*ads));
|
||||||
|
|
||||||
ads->realm = realm? strdup(realm) : NULL;
|
ads->realm = realm? strdup(realm) : NULL;
|
||||||
@ -84,17 +104,42 @@ ADS_STRUCT *ads_init(const char *realm,
|
|||||||
ads->bind_path = bind_path? strdup(bind_path) : NULL;
|
ads->bind_path = bind_path? strdup(bind_path) : NULL;
|
||||||
ads->ldap_port = LDAP_PORT;
|
ads->ldap_port = LDAP_PORT;
|
||||||
|
|
||||||
|
if (!ads->realm) {
|
||||||
|
ads->realm = lp_realm();
|
||||||
|
}
|
||||||
if (!ads->bind_path) {
|
if (!ads->bind_path) {
|
||||||
ads->bind_path = ads_build_dn(ads->realm);
|
ads->bind_path = ads_build_dn(ads->realm);
|
||||||
}
|
}
|
||||||
|
if (!ads->ldap_server) {
|
||||||
|
ads->ldap_server = find_ldap_server(ads);
|
||||||
|
}
|
||||||
|
if (!ads->kdc_server) {
|
||||||
|
/* assume its the same as LDAP */
|
||||||
|
ads->kdc_server = ads->ldap_server? strdup(ads->ldap_server) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return ads;
|
return ads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
free the memory used by the ADS structure initialized with 'ads_init(...)'
|
||||||
|
*/
|
||||||
|
void ads_destroy(ADS_STRUCT *ads)
|
||||||
|
{
|
||||||
|
if (ads->ld) ldap_unbind(ads->ld);
|
||||||
|
SAFE_FREE(ads->realm);
|
||||||
|
SAFE_FREE(ads->ldap_server);
|
||||||
|
SAFE_FREE(ads->kdc_server);
|
||||||
|
SAFE_FREE(ads->bind_path);
|
||||||
|
ZERO_STRUCTP(ads);
|
||||||
|
free(ads);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
this is a minimal interact function, just enough for SASL to talk
|
this is a minimal interact function, just enough for SASL to talk
|
||||||
GSSAPI/kerberos to W2K
|
GSSAPI/kerberos to W2K
|
||||||
|
Error handling is a bit of a problem. I can't see how to get Cyrus-sasl
|
||||||
|
to give sensible errors
|
||||||
*/
|
*/
|
||||||
static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in)
|
static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in)
|
||||||
{
|
{
|
||||||
@ -102,7 +147,7 @@ static int sasl_interact(LDAP *ld,unsigned flags,void *defaults,void *in)
|
|||||||
|
|
||||||
while (interact->id != SASL_CB_LIST_END) {
|
while (interact->id != SASL_CB_LIST_END) {
|
||||||
interact->result = strdup("");
|
interact->result = strdup("");
|
||||||
interact->len = 0;
|
interact->len = strlen(interact->result);
|
||||||
interact++;
|
interact++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +168,8 @@ int ads_connect(ADS_STRUCT *ads)
|
|||||||
}
|
}
|
||||||
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
|
||||||
|
|
||||||
rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL, 0,
|
rc = ldap_sasl_interactive_bind_s(ads->ld, NULL, NULL, NULL, NULL,
|
||||||
|
LDAP_SASL_QUIET,
|
||||||
sasl_interact, NULL);
|
sasl_interact, NULL);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -290,12 +336,11 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
LDAPMessage *res;
|
LDAPMessage *res;
|
||||||
char *principal;
|
|
||||||
|
|
||||||
rc = ads_find_machine_acct(ads, (void **)&res, hostname);
|
rc = ads_find_machine_acct(ads, (void **)&res, hostname);
|
||||||
if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) {
|
if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1) {
|
||||||
DEBUG(0, ("Host account for %s already exists\n", hostname));
|
DEBUG(0, ("Host account for %s already exists\n", hostname));
|
||||||
goto set_password;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ads_add_machine_acct(ads, hostname);
|
rc = ads_add_machine_acct(ads, hostname);
|
||||||
@ -311,14 +356,48 @@ int ads_join_realm(ADS_STRUCT *ads, const char *hostname)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_password:
|
|
||||||
asprintf(&principal, "HOST/%s@%s", hostname, ads->realm);
|
|
||||||
#if 0
|
|
||||||
krb5_set_principal_password(principal, ads->ldap_server, hostname, ads->realm);
|
|
||||||
#endif
|
|
||||||
free(principal);
|
|
||||||
|
|
||||||
return LDAP_SUCCESS;
|
return LDAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
delete a machine from the realm
|
||||||
|
*/
|
||||||
|
int ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
void *res;
|
||||||
|
char *hostnameDN;
|
||||||
|
|
||||||
|
rc = ads_find_machine_acct(ads, &res, hostname);
|
||||||
|
if (rc != LDAP_SUCCESS || ads_count_replies(ads, res) != 1) {
|
||||||
|
DEBUG(0, ("Host account for %s does not exist.\n", hostname));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hostnameDN = ldap_get_dn(ads->ld, (LDAPMessage *)res);
|
||||||
|
rc = ldap_delete_s(ads->ld, hostnameDN);
|
||||||
|
ldap_memfree(hostnameDN);
|
||||||
|
if (rc != LDAP_SUCCESS) {
|
||||||
|
DEBUG(0, ("ldap_delete_s: %s\n", ads_errstr(rc)));
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ads_find_machine_acct(ads, &res, hostname);
|
||||||
|
if (rc == LDAP_SUCCESS && ads_count_replies(ads, res) == 1 ) {
|
||||||
|
DEBUG(0, ("Failed to remove host account.\n"));
|
||||||
|
/*hmmm, we need NTSTATUS */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LDAP_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS ads_set_machine_password(ADS_STRUCT *ads,
|
||||||
|
const char *hostname,
|
||||||
|
const char *password)
|
||||||
|
{
|
||||||
|
return krb5_set_password(ads->kdc_server, hostname, ads->realm, password);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -95,6 +95,7 @@ DATA_BLOB krb5_get_ticket(char *principal)
|
|||||||
krb5_context context;
|
krb5_context context;
|
||||||
krb5_auth_context auth_context = NULL;
|
krb5_auth_context auth_context = NULL;
|
||||||
DATA_BLOB ret;
|
DATA_BLOB ret;
|
||||||
|
krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL};
|
||||||
|
|
||||||
retval = krb5_init_context(&context);
|
retval = krb5_init_context(&context);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
@ -109,6 +110,12 @@ DATA_BLOB krb5_get_ticket(char *principal)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) {
|
||||||
|
DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n",
|
||||||
|
error_message(retval)));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
if ((retval = krb5_mk_req2(context,
|
if ((retval = krb5_mk_req2(context,
|
||||||
&auth_context,
|
&auth_context,
|
||||||
0,
|
0,
|
||||||
|
@ -114,6 +114,7 @@ typedef struct
|
|||||||
char *szSocketOptions;
|
char *szSocketOptions;
|
||||||
char *szWorkGroup;
|
char *szWorkGroup;
|
||||||
char *szRealm;
|
char *szRealm;
|
||||||
|
char *szADSserver;
|
||||||
char **szDomainAdminGroup;
|
char **szDomainAdminGroup;
|
||||||
char **szDomainGuestGroup;
|
char **szDomainGuestGroup;
|
||||||
char *szUsernameMap;
|
char *szUsernameMap;
|
||||||
@ -650,6 +651,7 @@ static struct parm_struct parm_table[] = {
|
|||||||
{"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
|
{"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
|
||||||
{"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
|
{"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
|
||||||
{"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC},
|
{"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC},
|
||||||
|
{"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC},
|
||||||
{"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC},
|
{"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC},
|
||||||
{"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
|
{"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
|
||||||
{"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0},
|
{"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0},
|
||||||
@ -1459,6 +1461,7 @@ FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
|
|||||||
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
|
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
|
||||||
FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup)
|
FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup)
|
||||||
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
|
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
|
||||||
|
FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
|
||||||
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
|
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
|
||||||
#ifdef USING_GROUPNAME_MAP
|
#ifdef USING_GROUPNAME_MAP
|
||||||
FN_GLOBAL_STRING(lp_groupname_map, &Globals.szGroupnameMap)
|
FN_GLOBAL_STRING(lp_groupname_map, &Globals.szGroupnameMap)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Unix SMB/Netbios implementation.
|
Unix SMB/Netbios implementation.
|
||||||
Version 3.0.
|
Version 3.0.
|
||||||
Samba registry functions
|
Copyright (C) Andrew Tridgell 1992-2001
|
||||||
Copyright (C) Andrew Tridgell 1992-1998
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -53,7 +52,7 @@ void *secrets_fetch(char *key, size_t *size)
|
|||||||
{
|
{
|
||||||
TDB_DATA kbuf, dbuf;
|
TDB_DATA kbuf, dbuf;
|
||||||
if (!tdb)
|
if (!tdb)
|
||||||
return False;
|
return NULL;
|
||||||
kbuf.dptr = key;
|
kbuf.dptr = key;
|
||||||
kbuf.dsize = strlen(key);
|
kbuf.dsize = strlen(key);
|
||||||
dbuf = tdb_fetch(tdb, kbuf);
|
dbuf = tdb_fetch(tdb, kbuf);
|
||||||
@ -142,8 +141,18 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
|
|||||||
time_t *pass_last_set_time)
|
time_t *pass_last_set_time)
|
||||||
{
|
{
|
||||||
struct machine_acct_pass *pass;
|
struct machine_acct_pass *pass;
|
||||||
|
char *plaintext;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
plaintext = secrets_fetch_machine_password();
|
||||||
|
if (plaintext) {
|
||||||
|
/* we have an ADS password - use that */
|
||||||
|
DEBUG(4,("Using ADS machine password\n"));
|
||||||
|
E_md4hash((uchar *)plaintext, ret_pwd);
|
||||||
|
SAFE_FREE(plaintext);
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
|
if (!(pass = secrets_fetch(trust_keystr(domain), &size)) ||
|
||||||
size != sizeof(*pass))
|
size != sizeof(*pass))
|
||||||
return False;
|
return False;
|
||||||
@ -168,6 +177,27 @@ BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16])
|
|||||||
return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
|
return secrets_store(trust_keystr(domain), (void *)&pass, sizeof(pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Routine to set the plaintext machine account password for a realm
|
||||||
|
the password is assumed to be a null terminated ascii string
|
||||||
|
************************************************************************/
|
||||||
|
BOOL secrets_store_machine_password(char *pass)
|
||||||
|
{
|
||||||
|
return secrets_store(SECRETS_MACHINE_PASSWORD, pass, strlen(pass)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
Routine to fetch the plaintext machine account password for a realm
|
||||||
|
the password is assumed to be a null terminated ascii string
|
||||||
|
************************************************************************/
|
||||||
|
char *secrets_fetch_machine_password(void)
|
||||||
|
{
|
||||||
|
return (char *)secrets_fetch(SECRETS_MACHINE_PASSWORD, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
Routine to delete the trust account password file for a domain.
|
Routine to delete the trust account password file for a domain.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
@ -2464,8 +2464,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
|
|||||||
{
|
{
|
||||||
pstring key;
|
pstring key;
|
||||||
NT_PRINTER_INFO_LEVEL_2 info;
|
NT_PRINTER_INFO_LEVEL_2 info;
|
||||||
int len = 0,
|
int len = 0;
|
||||||
devmode_length = 0;
|
|
||||||
TDB_DATA kbuf, dbuf;
|
TDB_DATA kbuf, dbuf;
|
||||||
fstring printername;
|
fstring printername;
|
||||||
|
|
||||||
|
@ -426,8 +426,6 @@ static NTSTATUS cmd_lsa_lookupprivvalue(struct cli_state *cli,
|
|||||||
{
|
{
|
||||||
POLICY_HND pol;
|
POLICY_HND pol;
|
||||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
DOM_SID sid;
|
|
||||||
LUID luid;
|
LUID luid;
|
||||||
|
|
||||||
if (argc != 2 ) {
|
if (argc != 2 ) {
|
||||||
|
@ -122,7 +122,7 @@ END {
|
|||||||
gotstart = 1;
|
gotstart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( $0 ~ /^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
|
if( $0 ~ /^ADS_STRUCT|^DATA_BLOB|^ASN1_DATA|^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element|^NT_DEVICEMODE|^enum.*\(|^NT_USER_TOKEN|^SAM_ACCOUNT/ ) {
|
||||||
gotstart = 1;
|
gotstart = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,16 +73,12 @@ static int reply_spnego_kerberos(connection_struct *conn,
|
|||||||
DATA_BLOB *secblob)
|
DATA_BLOB *secblob)
|
||||||
{
|
{
|
||||||
DATA_BLOB ticket;
|
DATA_BLOB ticket;
|
||||||
krb5_context context;
|
|
||||||
krb5_auth_context auth_context = NULL;
|
|
||||||
krb5_keytab keytab = NULL;
|
|
||||||
krb5_data packet;
|
|
||||||
krb5_ticket *tkt = NULL;
|
|
||||||
int ret;
|
|
||||||
char *realm, *client, *p;
|
char *realm, *client, *p;
|
||||||
const struct passwd *pw;
|
const struct passwd *pw;
|
||||||
char *user;
|
char *user;
|
||||||
int sess_vuid;
|
int sess_vuid;
|
||||||
|
NTSTATUS ret;
|
||||||
|
DATA_BLOB auth_data;
|
||||||
auth_serversupplied_info *server_info = NULL;
|
auth_serversupplied_info *server_info = NULL;
|
||||||
|
|
||||||
realm = lp_realm();
|
realm = lp_realm();
|
||||||
@ -91,38 +87,9 @@ static int reply_spnego_kerberos(connection_struct *conn,
|
|||||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = krb5_init_context(&context);
|
ret = ads_verify_ticket(&ticket, &client, &auth_data);
|
||||||
if (ret) {
|
if (!NT_STATUS_IS_OK(ret)) {
|
||||||
DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret)));
|
DEBUG(1,("Failed to verify incoming ticket!\n"));
|
||||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
packet.length = ticket.length;
|
|
||||||
packet.data = (krb5_pointer)ticket.data;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
file_save("/tmp/ticket.dat", ticket.data, ticket.length);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((ret = krb5_rd_req(context, &auth_context, &packet,
|
|
||||||
NULL, keytab, NULL, &tkt))) {
|
|
||||||
DEBUG(3,("krb5_rd_req failed (%s)\n",
|
|
||||||
error_message(ret)));
|
|
||||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (tkt->enc_part2) {
|
|
||||||
file_save("/tmp/authdata.dat",
|
|
||||||
tkt->enc_part2->authorization_data[0]->contents,
|
|
||||||
tkt->enc_part2->authorization_data[0]->length);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((ret = krb5_unparse_name(context, tkt->enc_part2->client,
|
|
||||||
&client))) {
|
|
||||||
DEBUG(3,("krb5_unparse_name failed (%s)\n",
|
|
||||||
error_message(ret)));
|
|
||||||
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
return ERROR_NT(NT_STATUS_LOGON_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,11 +37,6 @@
|
|||||||
|
|
||||||
#include <includes.h>
|
#include <includes.h>
|
||||||
|
|
||||||
struct functable {
|
|
||||||
char *funcname;
|
|
||||||
int (*fn)();
|
|
||||||
};
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/* Beginning of internationalization section. Translatable constants */
|
/* Beginning of internationalization section. Translatable constants */
|
||||||
/* should be kept in this area and referenced in the rest of the code. */
|
/* should be kept in this area and referenced in the rest of the code. */
|
||||||
@ -315,8 +310,8 @@ static struct in_addr dest_ip;
|
|||||||
run a function from a function table. If not found then
|
run a function from a function table. If not found then
|
||||||
call the specified usage function
|
call the specified usage function
|
||||||
*/
|
*/
|
||||||
static int run_function(int argc, const char **argv, struct functable *table,
|
int net_run_function(int argc, const char **argv, struct functable *table,
|
||||||
int (*usage_fn)(void))
|
int (*usage_fn)(void))
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (argc < 1) {
|
if (argc < 1) {
|
||||||
@ -506,16 +501,9 @@ static BOOL make_ipc_connection(unsigned flags)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int net_usage(void)
|
|
||||||
{
|
|
||||||
d_printf(NET_USAGE);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int file_usage(void)
|
static int general_usage(void)
|
||||||
{
|
{
|
||||||
d_printf(NET_FILE_USAGE); /* command syntax */
|
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
||||||
d_printf(SERVER_USAGE);
|
d_printf(SERVER_USAGE);
|
||||||
d_printf(IPADDRESS_USAGE);
|
d_printf(IPADDRESS_USAGE);
|
||||||
@ -530,6 +518,20 @@ static int file_usage(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int net_usage(void)
|
||||||
|
{
|
||||||
|
d_printf(NET_USAGE);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int file_usage(void)
|
||||||
|
{
|
||||||
|
d_printf(NET_FILE_USAGE); /* command syntax */
|
||||||
|
|
||||||
|
general_usage();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -594,26 +596,13 @@ static int net_file(int argc, const char **argv)
|
|||||||
return cli_NetFileEnum(cli, NULL, NULL, file_fn);
|
return cli_NetFileEnum(cli, NULL, NULL, file_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, file_usage);
|
return net_run_function(argc, argv, func, file_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int share_usage(void)
|
static int share_usage(void)
|
||||||
{
|
{
|
||||||
d_printf(NET_SHARE_USAGE); /* command syntax */
|
d_printf(NET_SHARE_USAGE); /* command syntax */
|
||||||
|
general_usage();
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(COMMENT_USAGE);
|
|
||||||
d_printf(MAXUSERS_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,7 +675,7 @@ static int net_share(int argc, const char **argv)
|
|||||||
return cli_RNetShareEnum(cli, share_fn, NULL);
|
return cli_RNetShareEnum(cli, share_fn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, share_usage);
|
return net_run_function(argc, argv, func, share_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -694,17 +683,7 @@ static int session_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_SESSION_USAGE); /* command syntax */
|
d_printf(NET_SESSION_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* Target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* Misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +760,7 @@ static int net_session(int argc, const char **argv)
|
|||||||
return cli_NetSessionEnum(cli, list_sessions_func);
|
return cli_NetSessionEnum(cli, list_sessions_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, session_usage);
|
return net_run_function(argc, argv, func, session_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -797,18 +776,7 @@ static int server_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_SERVER_USAGE); /* command syntax */
|
d_printf(NET_SERVER_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, DOMAIN_MASTER); /* Target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* Misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,17 +791,7 @@ static int domain_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_DOMAIN_USAGE); /* command syntax */
|
d_printf(NET_DOMAIN_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -849,18 +807,7 @@ static int printq_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_PRINTQ_USAGE);
|
d_printf(NET_PRINTQ_USAGE);
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST);
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE);
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(JOBID_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -949,7 +896,7 @@ static int net_printq(int argc, const char **argv)
|
|||||||
return cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
|
return cli_NetPrintQEnum(cli, enum_queue, enum_jobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, printq_usage);
|
return net_run_function(argc, argv, func, printq_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -957,20 +904,7 @@ static int user_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_USER_USAGE); /* command syntax */
|
d_printf(NET_USER_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(COMMENT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
d_printf(LONG_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1047,7 +981,7 @@ int net_user(int argc, const char **argv)
|
|||||||
return cli_RNetUserEnum(cli, user_fn, NULL);
|
return cli_RNetUserEnum(cli, user_fn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, user_usage);
|
return net_run_function(argc, argv, func, user_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1055,20 +989,7 @@ static int group_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_GROUP_USAGE); /* command syntax */
|
d_printf(NET_GROUP_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(COMMENT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
d_printf(LONG_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1122,25 +1043,14 @@ static int net_group(int argc, const char **argv)
|
|||||||
return cli_RNetGroupEnum(cli, group_fn, NULL);
|
return cli_RNetGroupEnum(cli, group_fn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, group_usage);
|
return net_run_function(argc, argv, func, group_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int groupmember_usage(void)
|
static int groupmember_usage(void)
|
||||||
{
|
{
|
||||||
d_printf(NET_GROUPMEMBER_USAGE); /* command syntax */
|
d_printf(NET_GROUPMEMBER_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, LOCAL_HOST); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,25 +1091,14 @@ static int net_groupmember(int argc, const char **argv)
|
|||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
return run_function(argc, argv, func, groupmember_usage);
|
return net_run_function(argc, argv, func, groupmember_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_usage(void)
|
static int validate_usage(void)
|
||||||
{
|
{
|
||||||
d_printf(NET_VALIDATE_USAGE); /* command syntax */
|
d_printf(NET_VALIDATE_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,17 +1112,7 @@ static int service_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_SERVICE_USAGE); /* command syntax */
|
d_printf(NET_SERVICE_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1257,25 +1146,14 @@ static int net_service(int argc, const char **argv)
|
|||||||
return cli_RNetServiceEnum(cli, group_fn, NULL);
|
return cli_RNetServiceEnum(cli, group_fn, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return run_function(argc, argv, func, service_usage);
|
return net_run_function(argc, argv, func, service_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int password_usage(void)
|
static int password_usage(void)
|
||||||
{
|
{
|
||||||
d_printf(NET_PASSWORD_USAGE); /* command syntax */
|
d_printf(NET_PASSWORD_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,18 +1172,7 @@ static int admin_usage(void)
|
|||||||
{
|
{
|
||||||
d_printf(NET_ADMIN_USAGE); /* command syntax */
|
d_printf(NET_ADMIN_USAGE); /* command syntax */
|
||||||
|
|
||||||
d_printf(TARGET_USAGE, GLBL_LCL_MASTER); /* target options */
|
general_usage();
|
||||||
d_printf(SERVER_USAGE);
|
|
||||||
d_printf(IPADDRESS_USAGE);
|
|
||||||
d_printf(WORKGROUP_USAGE);
|
|
||||||
|
|
||||||
d_printf(MISC_OPT_USAGE); /* misc options */
|
|
||||||
d_printf(PORT_USAGE);
|
|
||||||
d_printf(MYWORKGROUP_USAGE);
|
|
||||||
d_printf(DEBUG_USAGE);
|
|
||||||
d_printf(MYNAME_USAGE);
|
|
||||||
d_printf(USER_USAGE);
|
|
||||||
d_printf(CONF_USAGE);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1316,18 +1183,6 @@ static int net_admin(int argc, const char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int join_usage(void)
|
|
||||||
{
|
|
||||||
d_printf(ERRMSG_NOT_IMPLEMENTED);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int net_join(int argc, const char **argv)
|
|
||||||
{
|
|
||||||
d_printf(ERRMSG_NOT_IMPLEMENTED);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int help_usage(void)
|
static int help_usage(void)
|
||||||
{
|
{
|
||||||
d_printf("\n"\
|
d_printf("\n"\
|
||||||
@ -1358,10 +1213,10 @@ static int net_help(int argc, const char **argv)
|
|||||||
{"ADMIN", admin_usage},
|
{"ADMIN", admin_usage},
|
||||||
{"SERVICE", service_usage},
|
{"SERVICE", service_usage},
|
||||||
{"PASSWORD", password_usage},
|
{"PASSWORD", password_usage},
|
||||||
{"JOIN", join_usage},
|
{"JOIN", net_join_usage},
|
||||||
{NULL, NULL}};
|
{NULL, NULL}};
|
||||||
|
|
||||||
return run_function(argc, argv, func, help_usage);
|
return net_run_function(argc, argv, func, help_usage);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* main function table */
|
/* main function table */
|
||||||
@ -1397,6 +1252,7 @@ int main(int argc,char *argv[])
|
|||||||
const char ** argv_new;
|
const char ** argv_new;
|
||||||
poptContext pc;
|
poptContext pc;
|
||||||
char *servicesf = dyn_CONFIGFILE;
|
char *servicesf = dyn_CONFIGFILE;
|
||||||
|
extern pstring global_myname;
|
||||||
|
|
||||||
struct poptOption long_options[] = {
|
struct poptOption long_options[] = {
|
||||||
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
|
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
|
||||||
@ -1479,10 +1335,17 @@ int main(int argc,char *argv[])
|
|||||||
if (!opt_workgroup) {
|
if (!opt_workgroup) {
|
||||||
opt_workgroup = lp_workgroup();
|
opt_workgroup = lp_workgroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!*global_myname) {
|
||||||
|
char *p;
|
||||||
|
fstrcpy(global_myname, myhostname());
|
||||||
|
p = strchr_m(global_myname, '.');
|
||||||
|
if (p) *p = 0;
|
||||||
|
}
|
||||||
|
|
||||||
load_interfaces();
|
load_interfaces();
|
||||||
|
|
||||||
rc = run_function(argc_new-1, argv_new+1, net_func, net_usage);
|
rc = net_run_function(argc_new-1, argv_new+1, net_func, net_usage);
|
||||||
|
|
||||||
DEBUG(2,("return code = %d\n", rc));
|
DEBUG(2,("return code = %d\n", rc));
|
||||||
return rc;
|
return rc;
|
||||||
|
143
source3/utils/net_join.c
Normal file
143
source3/utils/net_join.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
Samba Unix/Linux SMB client library
|
||||||
|
Version 3.0
|
||||||
|
join a realm
|
||||||
|
Copyright (C) 2001 Andrew Tridgell (tridge@samba.org)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
#if HAVE_ADS
|
||||||
|
|
||||||
|
/* a lame random number generator - used /dev/urandom if possible */
|
||||||
|
static unsigned one_random(void)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
static int initialised;
|
||||||
|
unsigned ret;
|
||||||
|
|
||||||
|
if (!initialised) {
|
||||||
|
initialised = 1;
|
||||||
|
fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
srandom(time(NULL) ^ getpid());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
return random();
|
||||||
|
}
|
||||||
|
|
||||||
|
read(fd, &ret, sizeof(ret));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate a simple random password of 15 chars - not a cryptographic one
|
||||||
|
*/
|
||||||
|
static char *generate_random_password(int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *pass;
|
||||||
|
|
||||||
|
if (!(pass = malloc(len+1)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i=0; i<len; ) {
|
||||||
|
char c = one_random() & 0x7f;
|
||||||
|
if (!isalnum(c) && !ispunct(c)) continue;
|
||||||
|
pass[i++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int net_join_usage(void)
|
||||||
|
{
|
||||||
|
d_printf("\nnet join"\
|
||||||
|
"\n\tjoins the local machine to a ADS realm\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_join(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
char *ldap_host;
|
||||||
|
char *hostname;
|
||||||
|
char *realm;
|
||||||
|
ADS_STRUCT *ads;
|
||||||
|
int rc;
|
||||||
|
char *password;
|
||||||
|
extern pstring global_myname;
|
||||||
|
NTSTATUS status;
|
||||||
|
|
||||||
|
hostname = strdup(global_myname);
|
||||||
|
strlower(hostname);
|
||||||
|
realm = lp_realm();
|
||||||
|
ldap_host = lp_ads_server();
|
||||||
|
if (!*ldap_host) ldap_host = NULL;
|
||||||
|
if (!*realm) realm = NULL;
|
||||||
|
|
||||||
|
if (!secrets_init()) {
|
||||||
|
DEBUG(1,("Failed to initialise secrets database\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
password = generate_random_password(15);
|
||||||
|
|
||||||
|
ads = ads_init(realm, ldap_host, NULL);
|
||||||
|
|
||||||
|
rc = ads_connect(ads);
|
||||||
|
if (rc) {
|
||||||
|
d_printf("ads_connect: %s\n", ads_errstr(rc));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ads_join_realm(ads, hostname);
|
||||||
|
if (rc) {
|
||||||
|
d_printf("ads_join_realm: %s\n", ads_errstr(rc));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ads_set_machine_password(ads, hostname, password);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
d_printf("ads_set_machine_password: %s\n", get_nt_error_msg(status));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!secrets_store_machine_password(password)) {
|
||||||
|
DEBUG(1,("Failed to save machine password\n"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
d_printf("Joined %s to realm %s\n", hostname, realm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
int net_join_usage(void)
|
||||||
|
{
|
||||||
|
d_printf("ADS support not compiled in\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int net_join(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
return net_join_usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user