selftest: Run krb5.kdc with an account that has a UPN and an SPN
[kai/samba-autobuild/.git] / source3 / nmbd / nmbd_nameregister.c
index 98f129aa892d872774ddbd528cd57eef7b6041b0..8b078e6859af3f92384c1625d5896b4158184576 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 #include "includes.h"
+#include "nmbd/nmbd.h"
 
 /* forward declarations */
 static void wins_next_registration(struct response_record *rrec);
@@ -104,6 +105,14 @@ static void register_name_response(struct subnet_record *subrec,
                         subrec->subnet_name, nmb->header.rcode, inet_ntoa(p->ip)));
                success = False;
        } else {
+               if (!ip_equal_v4(rrec->packet->ip, p->ip)) {
+                       DEBUG(5,("register_name_response: Ignoring WINS server response "
+                               "from IP %s, for name %s. We sent to IP %s\n",
+                               inet_ntoa(p->ip),
+                               nmb_namestr(answer_name),
+                               inet_ntoa(rrec->packet->ip)));
+                       return;
+               }
                /* Unicast - check to see if the response allows us to have the name. */
                if (nmb->header.opcode == NMB_WACK_OPCODE) {
                        /* WINS server is telling us to wait. Pretend we didn't get
@@ -473,17 +482,77 @@ void register_name(struct subnet_record *subrec,
 {
        struct nmb_name nmbname;
        nstring nname;
+       size_t converted_size;
 
        errno = 0;
-       push_ascii_nstring(nname, name);
-        if (errno == E2BIG) {
-               unstring tname;
-               pull_ascii_nstring(tname, sizeof(tname), nname);
-               DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n",
-                       name, tname));
-               make_nmb_name(&nmbname, tname, type);
-       } else {
+       converted_size = push_ascii_nstring(nname, name);
+       if (converted_size != (size_t)-1) {
+               /* Success. */
                make_nmb_name(&nmbname, name, type);
+       } else if (errno == E2BIG) {
+               /*
+                * Name converted to CH_DOS is too large.
+                * try to truncate.
+                */
+               char *converted_str_dos = NULL;
+               char *converted_str_unix = NULL;
+               bool ok;
+
+               converted_size = 0;
+
+               ok = convert_string_talloc(talloc_tos(),
+                               CH_UNIX,
+                               CH_DOS,
+                               name,
+                               strlen(name)+1,
+                               &converted_str_dos,
+                               &converted_size);
+               if (!ok) {
+                       DEBUG(0,("register_name: NetBIOS name %s cannot be "
+                               "converted. Failing to register name.\n",
+                               name));
+                       return;
+               }
+
+               /*
+                * As it's now CH_DOS codepage
+                * we truncate by writing '\0' at
+                * MAX_NETBIOSNAME_LEN-1 and then
+                * convert back to CH_UNIX which we
+                * need for the make_nmb_name() call.
+                */
+               if (converted_size >= MAX_NETBIOSNAME_LEN) {
+                       converted_str_dos[MAX_NETBIOSNAME_LEN-1] = '\0';
+               }
+
+               ok = convert_string_talloc(talloc_tos(),
+                               CH_DOS,
+                               CH_UNIX,
+                               converted_str_dos,
+                               strlen(converted_str_dos)+1,
+                               &converted_str_unix,
+                               &converted_size);
+               if (!ok) {
+                       DEBUG(0,("register_name: NetBIOS name %s cannot be "
+                               "converted back to CH_UNIX. "
+                               "Failing to register name.\n",
+                               converted_str_dos));
+                       TALLOC_FREE(converted_str_dos);
+                       return;
+               }
+
+               make_nmb_name(&nmbname, converted_str_unix, type);
+
+               TALLOC_FREE(converted_str_dos);
+               TALLOC_FREE(converted_str_unix);
+       } else {
+               /*
+                * Generic conversion error. Fail to register.
+                */
+               DEBUG(0,("register_name: NetBIOS name %s cannot be "
+                       "converted (%s). Failing to register name.\n",
+                       name, strerror(errno)));
+               return;
        }
 
        /* Always set the NB_ACTIVE flag on the name we are