Skip to content

[BUG] JIT user creation: $user[User::REALNAME] = false produces "0" in glpi_users.realname when surname claim is absent #91

Description

@rafaelfariasbsb

Environment

  • GLPI: 11.0.5
  • samlsso: 1.2.5
  • OS: Ubuntu 24.04 LTS
  • IdP: Microsoft Entra ID (Azure AD)
  • JIT: Enabled

Problem

When an IdP's SAML response does not include the http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname claim, JIT-created users end up with glpi_users.realname = "0" (the literal string "0") instead of empty/NULL. In our production environment this surfaced as users with "Sobrenome" displaying "0" in the GLPI user list — 7 affected out of ~2340.

This is unrelated to (but discovered while investigating the aftermath of) #90.

Root cause

In src/LoginFlow/User.php around line 473 (and 6 other places), when a claim is missing the code assigns false to the field:

// Surname
if(isset($claims[User::SCHEMA_SURNAME][0])){
    if(strlen($claims[User::SCHEMA_SURNAME][0]) <= 255){
        $user[User::REALNAME] = $claims[User::SCHEMA_SURNAME][0];
    }else{ ... }
}else{
    $user[User::REALNAME] = false;   // ← bug
}

PHP false in the input array passes through Sanitizer::sanitize() into $user->add() and gets persisted as the string "0" in the varchar(255) NULL DEFAULT NULL column realname. Same pattern repeats for:

Field Line Target column Visible impact
REALNAME 473 glpi_users.realname Shows "0" in UI (reported)
SAMLJOBTITLE 486 rule input Sloppy rule input
MOBILE 499 glpi_users.mobile Likely same "0" issue
PHONE 512 glpi_users.phone Likely same "0" issue
SAMLCOUNTRY 525 rule input Sloppy rule input
SAMLCITY 538 rule input Sloppy rule input
SAMLSTREET 551 rule input Sloppy rule input

Three of these (REALNAME, MOBILE, PHONE) land directly in glpi_users and produce the visible "0" bug.

Expected behavior

When a claim is absent, the corresponding field should be either:

  • Not set at all in $user (falls back to GLPI's default — NULL for these columns), or
  • Set to an empty string "" (also safe: produces empty VARCHAR)

Never false, because PHP's truthy-to-DB casting path inside GLPI's ORM writes it as "0".

Suggested fix

Minimal, surgical — replace = false; with = ""; for each of the 7 fields, or remove the else branches entirely:

// Surname
if(isset($claims[User::SCHEMA_SURNAME][0])){
    if(strlen($claims[User::SCHEMA_SURNAME][0]) <= 255){
        $user[User::REALNAME] = $claims[User::SCHEMA_SURNAME][0];
    }else{ ... }
}
// no else — if claim is absent, leave the field unset (uses column default)

Workaround applied locally

Patched User.php line 473:

-                $user[User::REALNAME] = false;
+                $user[User::REALNAME] = "";

Plus SQL cleanup for existing affected rows:

-- Identify affected users
SELECT id, name FROM glpi_users WHERE realname = '0';
-- Fix (after manually verifying correct names):
UPDATE glpi_users SET realname = '<correct_surname>' WHERE id = <id>;

Note

This is a separate bug from #90 (the is_recursive=0 issue), but both were discovered in the same production incident. Happy to open a PR with the full 7-field fix if maintainers prefer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions