3

I am running as root, but have the user's uid (e.g. 504). How can I work out the user's locale (in my case en_GB)? The following does not work:

setuid(user_uid);
fprintf(stderr,
        CFStringGetCStringPtr(CFLocaleGetIdentifier(CFLocaleCopyCurrent()),
                              kCFStringEncodingMacRoman);
setuid(0);

This outputs en_US for me.

fredley
  • 32,953
  • 42
  • 145
  • 236
  • A user doesn't have a locale. Only an *environment* has a locale. The environment depends on many factors, though, and is usually set up by a series of shell scripts when a user logs in. – Kerrek SB Nov 24 '11 at 16:21
  • @KerrekSB Good point. Any idea how to get started in this situation? – fredley Nov 24 '11 at 16:23
  • @Crawl the user's directory, grep all files for occurrences of locale `export`s and anticipate what the user will type into her command line! Exhuming the `bash_history` file might give you statistical information about past behaviour; e.g. if you see lots of `LC_ALL=en_AU.utf8 ./myprog`, you know that the user might like kangaroos... – Kerrek SB Nov 24 '11 at 16:25
  • If it's really that much effort, how come `setuid(0)` is changing the result of `CFLocaleCopyCurrent()` but `setuid(user_uid)` isn't? – fredley Nov 24 '11 at 16:27
  • How is `setuid(0)` "changing" it? Usually when you obtain elevated privileges, the OS should reset or clear the entire environment so that unprivileged users can't inject anything into the privileged context. I assume that would set the locale to `C` or something like that. – Kerrek SB Nov 24 '11 at 16:30
  • @KerrekSB It's changing it to `en_US`, I'm not sure why. My colleague's Mac changes it to `en_GB`, which seems strange. – fredley Nov 24 '11 at 16:31
  • Hm, MacOSX might have some additional non-standard features that track a sort of system-wise locale default. In that case I woudln't know; we'll have to wait for some Macsperts. – Kerrek SB Nov 24 '11 at 16:36

2 Answers2

1

This information is contained in GlobalPreferences.plist, so running:

$ defaults read /Library/Preferences/.GlobalPreferences AppleLocale

gives the desired result.

fredley
  • 32,953
  • 42
  • 145
  • 236
-1

You can't, because it doesn't exist. The locale is controled by environment variables, and can change dynamically, and from window to window and even from application to application (i.e. if the user started a program with:

env LC_LANG=fr_FR program_name ...

.) Under Unix, you might be able to get user's default locale by doing something like:

FILE* in = popen( "su -c 'env | grep ^LC_ ; env | grep ^LANG' - user", "r" );

, then reading and parsing the input, but I don't think that there's anything simpler.

James Kanze
  • 150,581
  • 18
  • 184
  • 329