r24789: Add implementation of machine-authenticated connection to netlogon
authorRafal Szczesniak <mimir@samba.org>
Wed, 29 Aug 2007 19:55:13 +0000 (19:55 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:21 +0000 (12:30 -0500)
pipe used when connecting to win2k and newer domain controllers. The
server may be configured to deny anonymous netlogon connections which
would stop domain join verification step. Still, winnt domains require
such smb sessions not to be authenticated using machine credentials.
Creds employed in smb session cannot have a username in upn form, so
provide the separate function to use machine account.

rafal
(This used to be commit 30d99d8ac3379caadc5bdb353977149d1ee16403)

source3/utils/net.c
source3/utils/net_ads.c
source3/utils/net_rpc_join.c

index 5a4568e033e1bd09f091ad487ae48b0a448f58e5..c37e426d531538c47c9c122713212faf80f32d72 100644 (file)
@@ -341,10 +341,10 @@ NTSTATUS connect_dst_pipe(struct cli_state **cli_dst, struct rpc_pipe_client **p
 }
 
 /****************************************************************************
- Use the local machine's password for this session.
+ Use the local machine account (upn) and password for this session.
 ****************************************************************************/
 
-int net_use_machine_password(void) 
+int net_use_upn_machine_account(void) 
 {
        char *user_name = NULL;
 
@@ -353,7 +353,6 @@ int net_use_machine_password(void)
                exit(1);
        }
 
-       user_name = NULL;
        opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
        if (asprintf(&user_name, "%s$@%s", global_myname(), lp_realm()) == -1) {
                return -1;
@@ -362,6 +361,27 @@ int net_use_machine_password(void)
        return 0;
 }
 
+/****************************************************************************
+ Use the machine account name and password for this session.
+****************************************************************************/
+
+int net_use_machine_account(void)
+{
+       char *user_name = NULL;
+               
+       if (!secrets_init()) {
+               d_fprintf(stderr, "ERROR: Unable to open secrets database\n");
+               exit(1);
+       }
+
+       opt_password = secrets_fetch_machine_password(opt_target_workgroup, NULL, NULL);
+       if (asprintf(&user_name, "%s$", global_myname()) == -1) {
+               return -1;
+       }
+       opt_user_name = user_name;
+       return 0;
+}
+
 BOOL net_find_server(const char *domain, unsigned flags, struct in_addr *server_ip, char **server_name)
 {
        const char *d = domain ? domain : opt_target_workgroup;
@@ -1044,7 +1064,7 @@ static struct functable net_func[] = {
                /* it is very useful to be able to make ads queries as the
                   machine account for testing purposes and for domain leave */
 
-               net_use_machine_password();
+               net_use_upn_machine_account();
        }
 
        if (!opt_password) {
index f4fc9470f67b3f3a95967967cfa203468777fedb..bb7945dbf5298738033d0639841c568555e8d19b 100644 (file)
@@ -882,7 +882,7 @@ static NTSTATUS net_ads_join_ok(void)
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       net_use_machine_password();
+       net_use_upn_machine_account();
 
        status = ads_startup(True, &ads);
        if (!ADS_ERR_OK(status)) {
@@ -2187,7 +2187,7 @@ int net_ads_changetrustpw(int argc, const char **argv)
                return -1;
        }
 
-       net_use_machine_password();
+       net_use_upn_machine_account();
 
        use_in_memory_ccache();
 
index 558de8d8b489c3e136f78a2b3e65534ca7c4bbac..1097eb95754fd91d55c05f80c06a7df77e650e08 100644 (file)
  **/
 int net_rpc_join_ok(const char *domain, const char *server, struct in_addr *ip )
 {
+       enum security_types sec;
+       unsigned int conn_flags = NET_FLAGS_PDC;
        uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS|NETLOGON_NEG_SCHANNEL;
        struct cli_state *cli = NULL;
        struct rpc_pipe_client *pipe_hnd = NULL;
        struct rpc_pipe_client *netlogon_pipe = NULL;
        NTSTATUS ntret = NT_STATUS_UNSUCCESSFUL;
 
+       sec = (enum security_types)lp_security();
+
+       if (sec == SEC_ADS) {
+               /* Connect to IPC$ using machine account's credentials. We don't use anonymous
+                  connection here, as it may be denied by server's local policy. */
+               net_use_machine_account();
+
+       } else {
+               /* some servers (e.g. WinNT) don't accept machine-authenticated
+                  smb connections */
+               conn_flags |= NET_FLAGS_ANONYMOUS;
+       }
+
        /* Connect to remote machine */
-       if (!(cli = net_make_ipc_connection_ex(domain, server, ip, (NET_FLAGS_ANONYMOUS|NET_FLAGS_PDC)))) {
+       if (!(cli = net_make_ipc_connection_ex(domain, server, ip, conn_flags))) {
                return -1;
        }