s4:heimdal: import lorikeet-heimdal-202201172009 (commit 5a0b45cd723628b3690ea848548b...
[samba.git] / source4 / heimdal / lib / krb5 / get_default_principal.c
index 44baa6d1c2cdfb51ca855a2f9392b692cae54489..35480740f6fc7774554d9da06bad9a18e1338dbf 100644 (file)
  * Try to find out what's a reasonable default principal.
  */
 
-static const char*
-get_env_user(void)
-{
-    const char *user = getenv("USER");
-    if(user == NULL)
-       user = getenv("LOGNAME");
-    if(user == NULL)
-       user = getenv("USERNAME");
-    return user;
-}
-
-#ifndef _WIN32
-
-/*
- * Will only use operating-system dependant operation to get the
- * default principal, for use of functions that in ccache layer to
- * avoid recursive calls.
- */
-
-krb5_error_code
+KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 _krb5_get_default_principal_local (krb5_context context,
                                   krb5_principal *princ)
 {
-    krb5_error_code ret;
-    const char *user;
-    uid_t uid;
+    const char *user = NULL;
+    const char *second_component = NULL;
+    char userbuf[128];
 
     *princ = NULL;
 
-    uid = getuid();
-    if(uid == 0) {
-       user = getlogin();
-       if(user == NULL)
-           user = get_env_user();
-       if(user != NULL && strcmp(user, "root") != 0)
-           ret = krb5_make_principal(context, princ, NULL, user, "root", NULL);
-       else
-           ret = krb5_make_principal(context, princ, NULL, "root", NULL);
-    } else {
-       struct passwd *pw = getpwuid(uid);
-       if(pw != NULL)
-           user = pw->pw_name;
-       else {
-           user = get_env_user();
-           if(user == NULL)
-               user = getlogin();
-       }
-       if(user == NULL) {
-           krb5_set_error_message(context, ENOTTY,
-                                  N_("unable to figure out current "
-                                     "principal", ""));
-           return ENOTTY; /* XXX */
-       }
-       ret = krb5_make_principal(context, princ, NULL, user, NULL);
-    }
-    return ret;
-}
-
-#else  /* _WIN32 */
-
-#define SECURITY_WIN32
-#include <security.h>
-
-krb5_error_code
-_krb5_get_default_principal_local(krb5_context context,
-                                 krb5_principal *princ)
-{
-    /* See if we can get the principal first.  We only expect this to
-       work if logged into a domain. */
-    {
-       char username[1024];
-       ULONG sz = sizeof(username);
-
-       if (GetUserNameEx(NameUserPrincipal, username, &sz)) {
-           return krb5_parse_name_flags(context, username,
-                                        KRB5_PRINCIPAL_PARSE_ENTERPRISE,
-                                        princ);
-       }
-    }
-
-    /* Just get the Windows username.  This should pretty much always
-       work. */
-    {
-       char username[1024];
-       DWORD dsz = sizeof(username);
-
-       if (GetUserName(username, &dsz)) {
-           return krb5_make_principal(context, princ, NULL, username, NULL);
-       }
-    }
-
-    /* Failing that, we look at the environment */
-    {
-       const char * username = get_env_user();
-
-       if (username == NULL) {
-           krb5_set_error_string(context,
-                                 "unable to figure out current principal");
-           return ENOTTY;      /* Really? */
-       }
-
-       return krb5_make_principal(context, princ, NULL, username, NULL);
+    /*
+     * NOTE: We prefer getlogin_r() (via roken_get_loginname()) to using $USER,
+     *       $LOGNAME, or getpwuid_r() (via roken_get_username()), in that
+     *       order, otherwise we won't figure out to output
+     *       <username>/root@DEFAULT_REALM.
+     */
+#ifndef WIN32
+    if (geteuid() == 0)
+        user = roken_get_loginname(userbuf, sizeof(userbuf));
+#endif
+    if (user == NULL)
+        user = roken_get_username(userbuf, sizeof(userbuf));
+    if (user == NULL) {
+        krb5_set_error_message(context, ENOTTY,
+                               N_("unable to figure out current principal",
+                                  ""));
+        return ENOTTY; /* XXX */
     }
-}
 
+#ifndef WIN32
+    if (!issuid() && getuid() == 0 && strcmp(user, "root") != 0)
+        second_component = "root"; /* We'll use <user>/root */
 #endif
+    return krb5_make_principal(context, princ, NULL, user,
+                               second_component, NULL);
+}
 
 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
 krb5_get_default_principal (krb5_context context,