diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4user.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk4user.ctr')
-rw-r--r-- | support/dktools/dk4user.ctr | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/support/dktools/dk4user.ctr b/support/dktools/dk4user.ctr new file mode 100644 index 0000000000..4d9d89afe4 --- /dev/null +++ b/support/dktools/dk4user.ctr @@ -0,0 +1,470 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2015-xxxx +license = bsd + + + +%% header + +/** @file + Get information about user + (login name and home directory). +*/ + +#ifndef DK4CONF_H_INCLUDED +#include "dk4conf.h" +#endif + +#ifndef DK4TYPES_H_INCLUDED +#include "dk4types.h" +#endif + +#ifndef DK4ERROR_H_INCLUDED +#include "dk4error.h" +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + +/** Get users login name. + @param pdst Pointer to destination buffer. + @param szdst Size of destination buffer (number of characters). + @param eff Flag: Retrieve information about effective user. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + CRT on Windows: Not used. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if pdst is NULL or szdst is 0, + - DK4_E_NOT_FOUND<br> + if the login name was not found, + - DK4_E_BUFFER_TOO_SMALL<br> + if the buffer is too small for the result. +*/ +int +dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp); + +/** Get users home directory. + @param pdst Pointer to destination buffer. + @param szdst Size of destination buffer (number of characters). + @param eff Flag: Retrieve information about effective user. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. + + CRT on Windows: Optional. + + Error codes: + - DK4_E_INVALID_ARGUMENTS<br> + if pdst is NULL or szdst is 0, + - DK4_E_NOT_FOUND<br> + if the login name, the user entry or the home + directory was not found, + - DK4_E_MEMORY<br> + if an internal memory allocation failed, + - DK4_E_SYNTAX<br> + if the retrieved registry entry on + Windows is not a string, + - DK4_E_BUFFER_TOO_SMALL<br> + if the pdst buffer or one of the internal buffers + is too small for the result. +*/ +int +dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp); + +#ifdef __cplusplus +} +#endif + + +%% module + + +#include "dk4user.h" +#include "dk4str8.h" +#include "dk4strw.h" +#include "dk4strd.h" +#include "dk4wregw.h" +#include "dk4wregc.h" +#include "dk4mem.h" +#include "dk4error.h" +#include "dk4masz.h" +#include "dk4mpl.h" + + +#if DK4_ON_WINDOWS +#ifndef WINDOWS_H_INCLUDED +#include <windows.h> +#define WINDOWS_H_INCLUDED 1 +#endif +#ifndef LM_H_INCLUDED +#include <lm.h> +#define LM_H_INCLUDED 1 +#endif +#ifndef SDDL_H_INCLUDED +#include <sddl.h> +#define SDDL_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_SYS_TYPES_H +#ifndef SYS_TYPES_H_INCLUDED +#include <sys/types.h> +#define SYS_TYPES_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_UNISTD_H +#ifndef UNISTD_H_INCLUDED +#include <unistd.h> +#define UNISTD_H_INCLUDED 1 +#endif +#endif + +#if DK4_HAVE_PWD_H +#ifndef PWD_H_INCLUDED +#include <pwd.h> +#define PWD_H_INCLUDED 1 +#endif +#endif + + + +$!trace-include + + + +#if DK4_ON_WINDOWS +static const wchar_t * const dk4user_kw[] = { +$!string-table prefix=L +# +# 0 ... 2 Registry key name and value name for profile dir +# +SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList +\\ +ProfileImagePath +# +# 3 4 5 6 +# +LOGONSERVER +USERPROFILE +HOMEDRIVE +HOMEPATH +$!end +}; +#endif + +int +dk4user_get_logname(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp) +{ +#if DK4_ON_WINDOWS + DWORD sz; + int back = 0; + $? "+ dk4user_get_logname (Windows)" + if ((NULL != pdst) && (0 < szdst)) { + sz = (DWORD)szdst; +#if DK4_CHAR_SIZE > 1 + if(GetUserNameW(pdst, &sz)) +#else + if(GetUserNameA(pdst, &sz)) +#endif + { + if (sz < szdst) { + pdst[sz] = dkT('\0'); + back = 1; + } else { + dk4error_set_simple_error_code(erp, DK4_E_BUFFER_TOO_SMALL); + } + } + else + { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4user_get_logname (Windows) %d", back + return back; +#else +#if DK4_CHAR_SIZE > 1 + dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); + return 0; +#else + struct passwd *pwent; + uid_t uid; + int back = 0; + $? "+ dk4user_get_logname (non-Windows, char)" + if ((NULL != pdst) && (0 < szdst)) { + if (0 != eff) { uid = geteuid(); } else { uid = getuid(); } + pwent = getpwuid(uid); + if (NULL != pwent) { + if (NULL != pwent->pw_name) { + if (0 != dk4str_cpy_s(pdst, szdst, pwent->pw_name, erp)) { + back = 1; + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4user_get_logname (non-Windows, char) %d", back + return back; +#endif +#endif +} + + + +#if DK4_ON_WINDOWS + + + +/** Obtain home directory information using one logon server. + @param pdst Destination buffer pointer. + @param szdst Destination buffer size (number of wchar_t). + @param lsn Logon server name, may be NULL. + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4user_get_i_ls_homedir( + wchar_t *pdst, size_t szdst, const wchar_t *lsn, dk4_er_t *erp +) +{ + wchar_t b1[DK4_MAX_PATH+16]; /* Buffer RegQueryValue() */ + wchar_t b2[DK4_MAX_PATH+16]; /* Buffer Expand...() */ + wchar_t logname[256]; /* Login name */ + dk4_er_t er; /* Error report */ + USER_INFO_4 *pbuf4 = NULL; /* User information */ + wchar_t *pStringSid = NULL; /* String SID */ + wchar_t *keyname = NULL; /* Registry key name */ + void *wrkey = NULL; /* Registry key */ + DWORD szlog = DK4_SIZEOF(logname,wchar_t); + size_t sz = 0; /* Key name length */ + int back = 0; /* Result */ + NET_API_STATUS nStatus = 0; /* Network op result */ + $? "+ dk4user_get_i_ls_homedir lsn=\"%!ws\"", TR_LSTR(lsn) + dk4error_init(&er); + if (GetUserNameW(logname, &szlog)) { $? ". user name found" + if (DK4_SIZEOF(logname,wchar_t) >= szlog) { $? ". name size ok" + logname[szlog] = L'\0'; + nStatus = NetUserGetInfo(lsn, logname, (DWORD)4, (LPBYTE *)(&pbuf4)); + if ((NERR_Success == nStatus) && (NULL != pbuf4)) { $? ". user info" + if (ConvertSidToStringSidW(pbuf4->usri4_user_sid, &pStringSid)) { + $? ". sid" + sz = dk4ma_size_t_add( + dk4ma_size_t_add( + 1, + dk4strw_len(dk4user_kw[0]), + &er + ), + dk4ma_size_t_add( + dk4strw_len(dk4user_kw[1]), + dk4strw_len(pStringSid), + &er + ), + &er + ); + if (DK4_E_NONE == er.ec) { $? ". size calc 1 ok" + (void)dk4ma_size_t_mul(sizeof(wchar_t), sz, &er); + if (DK4_E_NONE == er.ec) { $? ". size calc 2 ok" + keyname = dk4mem_calloc(sizeof(wchar_t),sz,&er); + if (NULL != keyname) { $? ". calloc ok" + (void)dk4strw_cpy_s(keyname, sz, dk4user_kw[0], NULL); + (void)dk4strw_cat_s(keyname, sz, dk4user_kw[1], NULL); + (void)dk4strw_cat_s(keyname, sz, pStringSid, NULL); + wrkey = dk4wreg_open_key_wc(DK4_WREGKEY_HKLM, keyname, 0, &er); + if (NULL != wrkey) { $? ". key opened" + back = dk4wreg_get_expanded_string_wc( + wrkey, + dk4user_kw[2], + pdst, szdst, + b1, DK4_SIZEOF(b1,wchar_t), + b2, (DK4_SIZEOF(b2,wchar_t)-2), + &er + ); $? ". back = %d", back + dk4wreg_close_key(wrkey); + } else { $? "! registry key" + /* ERROR: Failed to open key (reported) */ + } + dk4mem_free(keyname); + } else { $? "! memory" + /* ERROR: Memory (reported) */ + } + } else { $? "! size calc overflow" + /* ERROR: Overflow in size calculation (reported) */ + } + } else { $? "! size calc overflow" + /* ERROR: Overflow in size calculation (reported) */ + } + } else { $? "! failed to convert sid" + /* ERROR: Failed to convert SID */ + dk4error_set_simple_error_code(&er, DK4_E_NOT_FOUND); + } + if (NULL != pStringSid) { + LocalFree(pStringSid); + } + } else { $? "! failed to obtain info" + /* ERROR: No user info */ + } + if (NULL != pbuf4) { + NetApiBufferFree(pbuf4); + } + } else { $? "! user name too long" + /* ERROR: User name too long */ + dk4error_set_simple_error_code(&er, DK4_E_BUFFER_TOO_SMALL); + } + } else { $? "! user name not found" + /* ERROR: User name not found */ + } + if (0 == back) { + dk4error_copy(erp, &er); + } + $? "- dk4user_get_i_ls_homedir %d", back + return back; +} + + + +/** Find Windows home directory. + @param pdst Destination buffer pointer. + @param szdst Destination buffer size (number of wchar_t). + @param erp Error report, may be NULL. + @return 1 on success, 0 on error. +*/ +static +int +dk4user_get_i_homedir(wchar_t *pdst, size_t szdst, dk4_er_t *erp) +{ + dk4_er_t myerp; + wchar_t *lsn = NULL; + wchar_t *hop = NULL; + int back = 0; + $? "+ dk4user_get_i_homedir" + dk4error_init(&myerp); + back = dk4user_get_i_ls_homedir(pdst, szdst, NULL, &myerp); + $? ". back = %d", back + if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt" + lsn = _wgetenv(dk4user_kw[4]); $? ". userprofile" + if (NULL != lsn) { + back = dk4strw_cpy_s(pdst, szdst, lsn, &myerp); + $? ". back = %d", back + } else { $? "! userprofile" + } + } + if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt" + lsn = _wgetenv(dk4user_kw[5]); + hop = _wgetenv(dk4user_kw[6]); + if ((NULL != lsn) && (NULL != hop)) { $? ". drive / path" + if (0 != dk4strw_cpy_s(pdst, szdst, lsn, &myerp)) { + back = dk4strw_cat_s(pdst, szdst, hop, &myerp); + $? ". back = %d", back + } else { $? "! too long" + } + } else { $? "! drive / path" + } + } + if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt" + lsn = _wgetenv(dk4user_kw[3]); + if (NULL != lsn) { $? ". env ok" + back = dk4user_get_i_ls_homedir(pdst, szdst, lsn, &myerp); + $? ". back = %d", back + } + } + if ((0 == back) && (DK4_E_NONE == myerp.ec)) { $? ". attempt" + if (NULL != lsn) { $? ". lsn" + if (L'\\' == lsn[0]) { + if (L'\\' == lsn[1]) { + back = dk4user_get_i_ls_homedir(pdst, szdst, &(lsn[2]), &myerp); + $? ". back = %d", back + } else { $? "! lsn[1]" + } + } else { $? "! lsn[0]" + } + } else { $? "! lsn" + } + } + if ((0 == back) && (DK4_E_NONE == myerp.ec)) { + dk4error_set_simple_error_code(&myerp, DK4_E_NOT_FOUND); + } + if (0 == back) { + dk4error_copy(erp, &myerp); + } $? "- dk4user_get_i_homedir %d", back + return back; +} + +#endif + + +int +dk4user_get_homedir(dkChar *pdst, size_t szdst, int eff, dk4_er_t *erp) +{ +#if DK4_ON_WINDOWS +/* +++++ Windows +++++ */ +#if DK4_CHAR_SIZE == 1 + wchar_t homew[DK4_MAX_PATH]; +#endif + int back = 0; + $? "+ dk4user_get_homedir" + if ((NULL != pdst) && (0 < szdst)) { $? ". arguments" + *pdst = dkT('\0'); +#if DK4_CHAR_SIZE > 1 + $? ". wchar_t" + back = dk4user_get_i_homedir(pdst, szdst, erp); +#else + $? ". char" + if (0 != dk4user_get_i_homedir(homew, DK4_SIZEOF(homew,wchar_t), erp)) { + back = dk4recode_utf16_to_ansi(pdst, szdst, homew, erp); + } +#endif + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4user_get_homedir %d", back + return back; +/* ----- Windows ----- */ +#else +/* +++++ non-Windows +++++ */ +#if DK4_CHAR_SIZE > 1 +/* +++++ non-Windows wchar_t +++++ */ + dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); + return 0; +/* ----- non-Windows wchar_t ----- */ +#else +/* +++++ non-Windows char +++++ */ + struct passwd *pwent; + uid_t uid; + int back = 0; + $? "+ dk4user_get_homedir (non-windows, char)" + if ((NULL != pdst) && (0 < szdst)) { + if (0 != eff) { uid = geteuid(); } else { uid = getuid(); } + pwent = getpwuid(uid); + if (NULL != pwent) { + if (NULL != pwent->pw_dir) { + if (0 != dk4str8_cpy_s(pdst, szdst, pwent->pw_dir, erp)) { + back = 1; + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_NOT_FOUND); + } + } else { + dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); + } $? "- dk4user_get_homedir (non-windows, char) %d", back + return back; +/* ----- non-Windows char ----- */ +#endif +/* ----- non-Windows ----- */ +#endif +} + |