r11930: Add socket/packet handling code for kpasswdd
authorAndrew Bartlett <abartlet@samba.org>
Sun, 27 Nov 2005 02:02:44 +0000 (02:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:48 +0000 (13:46 -0500)
Allow ticket requests with only a netbios name to be considered 'null'
addresses, and therefore allowed by default.

Use the netbios address as the workstation name for the allowed
workstations check with krb5.

Andrew Bartlett

source/heimdal/kdc/kerberos5.c
source/kdc/kdc.c
source/kdc/pac-glue.c

index 3577a14e5fbf9eb93135a3c9181635b155ab5c4c..ccfa35b6381e88e6f87ce05760ba9933ebfa18b5 100644 (file)
@@ -758,11 +758,27 @@ check_addresses(krb5_context context,
     krb5_error_code ret;
     krb5_address addr;
     krb5_boolean result;
-    
+    krb5_boolean only_netbios = TRUE;
+    int i;
+
     if(config->check_ticket_addresses == 0)
        return TRUE;
 
-    if(addresses == NULL)
+    if(addresses == NULL) 
+       return config->allow_null_ticket_addresses;
+
+    for (i = 0; i < addresses->len; ++i) {
+           if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
+                   only_netbios = FALSE;
+           }
+    }
+
+    /* Windows sends it's netbios name, which I can only assume is
+     * used for the 'allowed workstations' check.  This is painful, but
+     * we still want to check IP addresses if they happen to be
+     * present. */
+
+    if(only_netbios)
        return config->allow_null_ticket_addresses;
     
     ret = krb5_sockaddr2address (context, from, &addr);
index 4e7865b5f9929a0949f432f94742c9817fe69d01..f220357708208ae9b1ecd5067621fd5699304aa7 100644 (file)
@@ -388,6 +388,19 @@ void kpasswdd_tcp_accept(struct stream_connection *conn)
        kdcconn->kdc     = kdc;
        kdcconn->process = kpasswdd_process;
        conn->private    = kdcconn;
+       kdcconn->packet = packet_init(kdcconn);
+       if (kdcconn->packet == NULL) {
+               stream_terminate_connection(conn, "kdc_tcp_accept: out of memory");
+               return;
+       }
+       packet_set_private(kdcconn->packet, kdcconn);
+       packet_set_socket(kdcconn->packet, conn->socket);
+       packet_set_callback(kdcconn->packet, kdc_tcp_recv);
+       packet_set_full_request(kdcconn->packet, packet_full_request_u32);
+       packet_set_error_handler(kdcconn->packet, kdc_tcp_recv_error);
+       packet_set_event_context(kdcconn->packet, conn->event.ctx);
+       packet_set_fde(kdcconn->packet, conn->event.fde);
+       packet_set_serialise(kdcconn->packet);
 }
 
 static const struct stream_server_ops kpasswdd_tcp_stream_ops = {
@@ -556,9 +569,6 @@ static void kdc_task_init(struct task_server *task)
        }
        krb5_kdc_default_config(kdc->config);
 
-       /* NAT and the like make this pointless, and painful */
-       kdc->config->check_ticket_addresses = FALSE;
-
        initialize_krb5_error_table();
 
        ret = smb_krb5_init_context(kdc, &kdc->smb_krb5_context);
index 03b53fa3af07c5f30ab8b65860084d89015737ba..bd4d3e6a2fe6f5aeb7731bed177ff428339dbe5a 100644 (file)
@@ -324,6 +324,8 @@ krb5_error_code wrap_pac(krb5_context context, krb5_data *pac, AuthorizationData
        TALLOC_CTX *tmp_ctx = talloc_new(entry_ex->private);
        struct hdb_ldb_private *private = talloc_get_type(entry_ex->private, struct hdb_ldb_private);
        char *name, *workstation = NULL;
+       int i;
+
        if (!tmp_ctx) {
                return ENOMEM;
        }
@@ -331,7 +333,26 @@ krb5_error_code wrap_pac(krb5_context context, krb5_data *pac, AuthorizationData
        ret = krb5_unparse_name(context, entry_ex->entry.principal, &name);
        if (ret != 0) {
                talloc_free(tmp_ctx);
+               return ret;
        }
+       
+       for (i=0; i < addresses->len; i++) {
+               if (addresses->val->addr_type == KRB5_ADDRESS_NETBIOS) {
+                       workstation = talloc_strndup(tmp_ctx, addresses->val->address.data, MIN(addresses->val->address.length, 15));
+                       if (workstation) {
+                               break;
+                       }
+               }
+       }
+
+       /* Strip space padding */
+       if (workstation) {
+               i = MIN(strlen(workstation), 15);
+               for (; i > 0 && workstation[i - 1] == ' '; i--) {
+                       workstation[i - 1] = '\0';
+               }
+       }
+
        nt_status = authsam_account_ok(tmp_ctx, 
                                       private->samdb, 
                                       MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,