winbind: Fix UPN handling in parse_domain_user()
[nivanova/samba-autobuild/.git] / source3 / winbindd / winbindd_util.c
index 9d67b4b1507d7fb688705b0faa1088f27684e6f3..fd4d2b1f9dea094100e5db2b57876cdb367c79fe 100644 (file)
@@ -1575,28 +1575,37 @@ static bool assume_domain(const char *domain)
        return False;
 }
 
-/* Parse a string of the form DOMAIN\user into a domain and a user */
-
-bool parse_domain_user(const char *domuser, fstring domain, fstring user)
+/* Parse a DOMAIN\user or UPN string into a domain, namespace and a user */
+bool parse_domain_user(const char *domuser,
+                      fstring namespace,
+                      fstring domain,
+                      fstring user)
 {
-       char *p = strchr(domuser,*lp_winbind_separator());
+       char *p = NULL;
+
+       if (strlen(domuser) == 0) {
+               return false;
+       }
 
-       if ( !p ) {
+       p = strchr(domuser, *lp_winbind_separator());
+       if (p != NULL) {
+               fstrcpy(user, p + 1);
+               fstrcpy(domain, domuser);
+               domain[PTR_DIFF(p, domuser)] = '\0';
+               fstrcpy(namespace, domain);
+       } else {
                fstrcpy(user, domuser);
-               p = strchr(domuser, '@');
 
-               if ( assume_domain(lp_workgroup()) && p == NULL) {
+               domain[0] = '\0';
+               namespace[0] = '\0';
+               p = strchr(domuser, '@');
+               if (p != NULL) {
+                       /* upn */
+                       fstrcpy(namespace, p + 1);
+               } else if (assume_domain(lp_workgroup())) {
                        fstrcpy(domain, lp_workgroup());
-               } else if (p != NULL) {
-                       fstrcpy(domain, p + 1);
-                       user[PTR_DIFF(p, domuser)] = 0;
-               } else {
-                       return False;
+                       fstrcpy(namespace, domain);
                }
-       } else {
-               fstrcpy(user, p+1);
-               fstrcpy(domain, domuser);
-               domain[PTR_DIFF(p, domuser)] = 0;
        }
 
        return strupper_m(domain);
@@ -1613,7 +1622,11 @@ bool parse_domain_user(const char *domuser, fstring domain, fstring user)
 
 bool canonicalize_username(fstring username_inout, fstring domain, fstring user)
 {
-       if (!parse_domain_user(username_inout, domain, user)) {
+       fstring namespace;
+       bool ok;
+
+       ok = parse_domain_user(username_inout, namespace, domain, user);
+       if (!ok) {
                return False;
        }
        slprintf(username_inout, sizeof(fstring) - 1, "%s%c%s",