UTF-8 and LDAP
Juergen Hasch
Hasch at t-online.de
Sat Feb 23 11:11:05 GMT 2002
Hi Andrew,
here is the patch for UTF-8 support with LDAP.
Actually these are three patches:
1. Add push_utf8_pstring and push_utf8_fstring I forgot last time.
Remove unused base_ptr in function call.
2. Convert some strings to/from UTF-8 when calling LDAP functions.
I assume here that not all parameters need to be in UTF-8.
Namely in ldap_search only the filter expression needs to be UTF-8,
base and attributes should not contain non-ascii chars.
Received strings from LDAP get UTF-8 converted in ads_pull_string
and ads_dump_string.
For ldap_modify_ext_s I needed to allocate space for the strings after
UTF-8 conversion using talloc_strdup in ads_mod_ber / ads_mod_var.
3. Replace all printf/fprintf function calls in wbinfo.c with
d_printf/d_fprintf. This way CH_DISPLAY will be used for
user output. No really critical fix :-)
These patches work for me, I get german characters with
"net ads", "wbinfo" and "getent".
...Juergen
--- lib/charcnv.orig Sat Feb 23 19:16:47 2002
+++ lib/charcnv.c Sat Feb 23 13:20:32 2002
@@ -400,7 +400,7 @@
dest_len is the maximum length allowed in the destination. If dest_len
is -1 then no maxiumum is used
****************************************************************************/
-int push_utf8(const void *base_ptr, void *dest, const char *src, int dest_len, int flags)
+int push_utf8(void *dest, const char *src, int dest_len, int flags)
{
int src_len = strlen(src);
pstring tmpbuf;
@@ -423,6 +423,16 @@
return convert_string(CH_UNIX, CH_UTF8, src, src_len, dest, dest_len);
}
+int push_utf8_fstring(void *dest, const char *src)
+{
+ return push_utf8(dest, src, sizeof(fstring), STR_TERMINATE);
+}
+
+int push_utf8_pstring(void *dest, const char *src)
+{
+ return push_utf8(dest, src, sizeof(pstring), STR_TERMINATE);
+}
+
/****************************************************************************
copy a string from a ucs2 source to a unix char* destination
flags can have:
@@ -476,7 +486,7 @@
return the number of bytes occupied by the string in src
the resulting string in "dest" is always null terminated
****************************************************************************/
-int pull_utf8(const void *base_ptr, char *dest, const void *src, int dest_len, int src_len, int flags)
+int pull_utf8(char *dest, const void *src, int dest_len, int src_len, int flags)
{
int ret;
@@ -494,12 +504,12 @@
int pull_utf8_pstring(char *dest, const void *src)
{
- return pull_utf8(NULL, dest, src, sizeof(pstring), -1, STR_TERMINATE);
+ return pull_utf8(dest, src, sizeof(pstring), -1, STR_TERMINATE);
}
int pull_utf8_fstring(char *dest, const void *src)
{
- return pull_utf8(NULL, dest, src, sizeof(fstring), -1, STR_TERMINATE);
+ return pull_utf8(dest, src, sizeof(fstring), -1, STR_TERMINATE);
}
/****************************************************************************
--- libads/ldap.orig Sun Feb 17 16:17:44 2002
+++ libads/ldap.c Sat Feb 23 19:01:10 2002
@@ -63,15 +63,17 @@
const char **attrs, void **res)
{
struct timeval timeout;
+ fstring utf8_exp;
int rc;
timeout.tv_sec = ADS_SEARCH_TIMEOUT;
timeout.tv_usec = 0;
*res = NULL;
+ pull_utf8_fstring(utf8_exp, exp);
rc = ldap_search_ext_s(ads->ld,
bind_path, scope,
- exp, (char **) attrs, 0, NULL, NULL,
+ utf8_exp, (char **) attrs, 0, NULL, NULL,
&timeout, LDAP_NO_LIMIT, (LDAPMessage **)res);
return ADS_ERROR(rc);
}
@@ -237,12 +242,13 @@
/*
add an attribute to the list, with values list to be built from args
*/
ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods,
int mod_op, char *name, ...)
{
va_list ap;
int num_vals, i, do_op;
char *value, **values;
+ fstring utf8_value;
/* count the number of values */
va_start(ap, name);
@@ -254,8 +260,12 @@
return ADS_ERROR(LDAP_NO_MEMORY);
va_start(ap, name);
for (i=0; (value = (char *) va_arg(ap, char *)) &&
- i < num_vals; i++)
- values[i] = value;
+ i < num_vals; i++) {
+ push_utf8_fstring(utf8_value,value);
+ values[i] = talloc_strdup(ctx,utf8_value);
+ }
va_end(ap);
values[i] = NULL;
do_op = mod_op;
@@ -266,12 +276,13 @@
return ads_modlist_add(ctx, mods, do_op, name, values);
}
ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods,
int mod_op, char *name, ...)
{
va_list ap;
int num_vals, i, do_op;
char *value, **values;
+ fstring utf8_value;
/* count the number of values */
va_start(ap, name);
@@ -284,8 +295,13 @@
return ADS_ERROR(LDAP_NO_MEMORY);
va_start(ap, name);
for (i=0; (value = (char *) va_arg(ap, char *)) &&
- i < num_vals; i++)
- values[i] = value;
+ i < num_vals; i++) {
+ push_utf8_fstring(utf8_value,value);
+ values[i] = talloc_strdup(ctx,utf8_value);
+ }
va_end(ap);
values[i] = NULL;
do_op = mod_op;
@@ -375,7 +391,6 @@
ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods)
{
int i;
-
/* find the end of the list, marked by NULL or -1 */
for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++);
/* make sure the end of the list is NULL */
@@ -436,22 +451,22 @@
if (!(samAccountName = talloc_asprintf(ctx, "%s$", hostname)))
goto done;
if (!(controlstr = talloc_asprintf(ctx, "%u",
UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT |
UF_TRUSTED_FOR_DELEGATION | UF_USE_DES_KEY_ONLY)))
goto done;
if (!(mods = ads_init_mods(ctx)))
goto done;
-
- ads_mod_add(ctx, &mods, "cn", hostname);
+
+ ads_mod_add(ctx, &mods, "cn", (char *)hostname);
ads_mod_add(ctx, &mods, "sAMAccountName", samAccountName);
ads_mod_add_var(ctx, &mods, LDAP_MOD_ADD, "objectClass",
"top", "person", "organizationalPerson",
"user", "computer", NULL);
ads_mod_add(ctx, &mods, "userPrincipalName", host_upn);
ads_mod_add(ctx, &mods, "servicePrincipalName", host_spn);
- ads_mod_add(ctx, &mods, "dNSHostName", hostname);
+ ads_mod_add(ctx, &mods, "dNSHostName", (char *)hostname);
ads_mod_add(ctx, &mods, "userAccountControl", controlstr);
ads_mod_add(ctx, &mods, "operatingSystem", "Samba");
ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION);
@@ -497,8 +512,10 @@
static void dump_string(const char *field, struct berval **values)
{
int i;
+ fstring utf8_val;
for (i=0; values[i]; i++) {
- printf("%s: %s\n", field, values[i]->bv_val);
+ pull_utf8_fstring(utf8_val,values[i]->bv_val);
+ d_printf("%s: %s\n", field, utf8_val);
}
}
@@ -681,12 +698,16 @@
{
char **values;
char *ret = NULL;
+ fstring utf8_field;
- values = ldap_get_values(ads->ld, msg, field);
+ push_utf8_fstring(utf8_field,field);
+ values = ldap_get_values(ads->ld, msg, utf8_field);
if (!values) return NULL;
if (values[0]) {
- ret = talloc_strdup(mem_ctx, values[0]);
+ fstring utf8_string;
+ pull_utf8_fstring(utf8_string,values[0]);
+ ret = talloc_strdup(mem_ctx, utf8_string);
}
ldap_value_free(values);
return ret;
@@ -699,7 +720,9 @@
void *msg, const char *field, uint32 *v)
{
char **values;
+ fstring utf8_field;
+ push_utf8_fstring(utf8_field,field);
values = ldap_get_values(ads->ld, msg, field);
if (!values) return False;
if (!values[0]) {
@@ -715,13 +738,15 @@
/*
pull a single DOM_SID from a ADS result
*/
BOOL ads_pull_sid(ADS_STRUCT *ads,
void *msg, const char *field, DOM_SID *sid)
{
struct berval **values;
BOOL ret = False;
+ fstring utf8_field;
- values = ldap_get_values_len(ads->ld, msg, field);
+ push_utf8_fstring(utf8_field,field);
+ values = ldap_get_values_len(ads->ld, msg, utf8_field);
if (!values) return False;
@@ -743,8 +768,10 @@
struct berval **values;
BOOL ret;
int count, i;
-
- values = ldap_get_values_len(ads->ld, msg, field);
+ fstring utf8_field;
+
+ push_utf8_fstring(utf8_field,field);
+ values = ldap_get_values_len(ads->ld, msg, utf8_field);
if (!values) return 0;
--- nsswitch/wbinfo.orig Tue Feb 19 21:01:05 2002
+++ nsswitch/wbinfo.c Thu Feb 21 23:18:48 2002
@@ -42,7 +42,7 @@
if (winbindd_request(WINBINDD_INFO, NULL, &response) !=
NSS_STATUS_SUCCESS) {
- printf("could not obtain winbind seperator!\n");
+ d_printf("could not obtain winbind seperator!\n");
/* HACK: (this module should not call lp_ funtions) */
return *lp_winbind_separator();
}
@@ -50,7 +50,7 @@
winbind_separator = response.data.info.winbind_separator;
if (!winbind_separator) {
- printf("winbind separator was NULL!\n");
+ d_printf("winbind separator was NULL!\n");
/* HACK: (this module should not call lp_ funtions) */
return *lp_winbind_separator();
}
@@ -70,7 +70,7 @@
if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
NSS_STATUS_SUCCESS) {
- printf("could not obtain winbind domain name!\n");
+ d_printf("could not obtain winbind domain name!\n");
/* HACK: (this module should not call lp_ funtions) */
return lp_workgroup();
@@ -124,7 +124,7 @@
return False;
for (i = 0; i < response.data.num_entries; i++)
- printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
+ d_printf("%d\n", (int)((gid_t *)response.extra_data)[i]);
SAFE_FREE(response.extra_data);
@@ -153,7 +153,7 @@
char *extra_data = (char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- printf("%s\n", name);
+ d_printf("%s\n", name);
SAFE_FREE(response.extra_data);
}
@@ -178,7 +178,7 @@
/* Display response */
if (response.extra_data) {
char *extra_data = (char *)response.extra_data;
- printf("%s", extra_data);
+ d_printf("%s", extra_data);
SAFE_FREE(response.extra_data);
}
@@ -200,9 +200,9 @@
if (result) {
if (response.data.num_entries == 0) {
- printf("Secret is good\n");
+ d_printf("Secret is good\n");
} else {
- printf("Secret is bad\n0x%08x\n",
+ d_printf("Secret is bad\n0x%08x\n",
response.data.num_entries);
}
@@ -232,7 +232,7 @@
/* Display response */
- printf("%s\n", response.data.sid.sid);
+ d_printf("%s\n", response.data.sid.sid);
return True;
}
@@ -257,7 +257,7 @@
/* Display response */
- printf("%s\n", response.data.sid.sid);
+ d_printf("%s\n", response.data.sid.sid);
return True;
}
@@ -282,7 +282,7 @@
/* Display response */
- printf("%d\n", (int)response.data.uid);
+ d_printf("%d\n", (int)response.data.uid);
return True;
}
@@ -305,7 +305,7 @@
/* Display response */
- printf("%d\n", (int)response.data.gid);
+ d_printf("%d\n", (int)response.data.gid);
return True;
}
@@ -330,7 +330,7 @@
/* Display response */
- printf("[%s]\\[%s] %d\n", response.data.name.dom_name, response.data.name.name, response.data.name.type);
+ d_printf("[%s]\\[%s] %d\n", response.data.name.dom_name, response.data.name.name, response.data.name.type);
return True;
}
@@ -356,7 +356,7 @@
/* Display response */
- printf("%s %d\n", response.data.sid.sid, response.data.sid.type);
+ d_printf("%s %d\n", response.data.sid.sid, response.data.sid.type);
return True;
}
@@ -389,10 +389,10 @@
/* Display response */
- printf("plaintext password authentication %s\n",
+ d_printf("plaintext password authentication %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
- printf("error code was %s (0x%x)\n", response.data.auth.nt_status_string, response.data.auth.nt_status);
+ d_printf("error code was %s (0x%x)\n", response.data.auth.nt_status_string, response.data.auth.nt_status);
return result == NSS_STATUS_SUCCESS;
}
@@ -441,10 +441,10 @@
/* Display response */
- printf("challenge/response password authentication %s\n",
+ d_printf("challenge/response password authentication %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
- printf("error code was %s (0x%x)\n",
+ d_printf("error code was %s (0x%x)\n",
response.data.auth.nt_status_string,
response.data.auth.nt_status);
@@ -476,7 +476,7 @@
extra_data = (char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- printf("%s\n", name);
+ d_printf("%s\n", name);
SAFE_FREE(response.extra_data);
@@ -506,7 +506,7 @@
extra_data = (char *)response.extra_data;
while(next_token(&extra_data, name, ",", sizeof(fstring)))
- printf("%s\n", name);
+ d_printf("%s\n", name);
SAFE_FREE(response.extra_data);
@@ -537,7 +537,7 @@
if (!secrets_store(SECRETS_AUTH_USER, username, strlen(username) + 1) ||
!secrets_store(SECRETS_AUTH_DOMAIN, domain, strlen(domain) + 1) ||
!secrets_store(SECRETS_AUTH_PASSWORD, password, strlen(password) + 1)) {
- fprintf(stderr, "error storing authenticated user info\n");
+ d_fprintf(stderr, "error storing authenticated user info\n");
return False;
}
@@ -552,7 +552,7 @@
/* Display response */
- printf("'ping' to winbindd %s\n",
+ d_printf("'ping' to winbindd %s\n",
(result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed");
return result == NSS_STATUS_SUCCESS;
@@ -562,22 +562,22 @@
static void usage(void)
{
- printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
+ d_printf("Usage: wbinfo -ug | -n name | -sSY sid | -UG uid/gid | -tm "
"| -a user%%password\n");
- printf("\t-u\t\t\tlists all domain users\n");
- printf("\t-g\t\t\tlists all domain groups\n");
- printf("\t-n name\t\t\tconverts name to sid\n");
- printf("\t-s sid\t\t\tconverts sid to name\n");
- printf("\t-U uid\t\t\tconverts uid to sid\n");
- printf("\t-G gid\t\t\tconverts gid to sid\n");
- printf("\t-S sid\t\t\tconverts sid to uid\n");
- printf("\t-Y sid\t\t\tconverts sid to gid\n");
- printf("\t-t\t\t\tcheck shared secret\n");
- printf("\t-m\t\t\tlist trusted domains\n");
- printf("\t-r user\t\t\tget user groups\n");
- printf("\t-a user%%password\tauthenticate user\n");
- printf("\t-p 'ping' winbindd to see if it is alive\n");
- printf("\t--sequence\t\tshow sequence numbers of all domains\n");
+ d_printf("\t-u\t\t\tlists all domain users\n");
+ d_printf("\t-g\t\t\tlists all domain groups\n");
+ d_printf("\t-n name\t\t\tconverts name to sid\n");
+ d_printf("\t-s sid\t\t\tconverts sid to name\n");
+ d_printf("\t-U uid\t\t\tconverts uid to sid\n");
+ d_printf("\t-G gid\t\t\tconverts gid to sid\n");
+ d_printf("\t-S sid\t\t\tconverts sid to uid\n");
+ d_printf("\t-Y sid\t\t\tconverts sid to gid\n");
+ d_printf("\t-t\t\t\tcheck shared secret\n");
+ d_printf("\t-m\t\t\tlist trusted domains\n");
+ d_printf("\t-r user\t\t\tget user groups\n");
+ d_printf("\t-a user%%password\tauthenticate user\n");
+ d_printf("\t-p 'ping' winbindd to see if it is alive\n");
+ d_printf("\t--sequence\t\tshow sequence numbers of all domains\n");
}
/* Main program */
@@ -632,7 +632,7 @@
}
if (!lp_load(dyn_CONFIGFILE, True, False, False)) {
- fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
+ d_fprintf(stderr, "wbinfo: error opening config file %s. Error was %s\n",
dyn_CONFIGFILE, strerror(errno));
exit(1);
}
@@ -652,7 +652,7 @@
while((opt = poptGetNextOpt(pc)) != -1) {
if (got_command) {
- fprintf(stderr, "No more than one command may be specified "
+ d_fprintf(stderr, "No more than one command may be specified "
"at once.\n");
exit(1);
}
@@ -669,76 +669,76 @@
exit(0);
case 'u':
if (!print_domain_users()) {
- printf("Error looking up domain users\n");
+ d_printf("Error looking up domain users\n");
return 1;
}
break;
case 'g':
if (!print_domain_groups()) {
- printf("Error looking up domain groups\n");
+ d_printf("Error looking up domain groups\n");
return 1;
}
break;
case 's':
if (!wbinfo_lookupsid(string_arg)) {
- printf("Could not lookup sid %s\n", string_arg);
+ d_printf("Could not lookup sid %s\n", string_arg);
return 1;
}
break;
case 'n':
if (!wbinfo_lookupname(string_arg)) {
- printf("Could not lookup name %s\n", string_arg);
+ d_printf("Could not lookup name %s\n", string_arg);
return 1;
}
break;
case 'U':
if (!wbinfo_uid_to_sid(int_arg)) {
- printf("Could not convert uid %d to sid\n", int_arg);
+ d_printf("Could not convert uid %d to sid\n", int_arg);
return 1;
}
break;
case 'G':
if (!wbinfo_gid_to_sid(int_arg)) {
- printf("Could not convert gid %d to sid\n",
+ d_printf("Could not convert gid %d to sid\n",
int_arg);
return 1;
}
break;
case 'S':
if (!wbinfo_sid_to_uid(string_arg)) {
- printf("Could not convert sid %s to uid\n",
+ d_printf("Could not convert sid %s to uid\n",
string_arg);
return 1;
}
break;
case 'Y':
if (!wbinfo_sid_to_gid(string_arg)) {
- printf("Could not convert sid %s to gid\n",
+ d_printf("Could not convert sid %s to gid\n",
string_arg);
return 1;
}
break;
case 't':
if (!wbinfo_check_secret()) {
- printf("Could not check secret\n");
+ d_printf("Could not check secret\n");
return 1;
}
break;
case 'm':
if (!wbinfo_list_domains()) {
- printf("Could not list trusted domains\n");
+ d_printf("Could not list trusted domains\n");
return 1;
}
break;
case OPT_SEQUENCE:
if (!wbinfo_show_sequence()) {
- printf("Could not show sequence numbers\n");
+ d_printf("Could not show sequence numbers\n");
return 1;
}
break;
case 'r':
if (!wbinfo_get_usergroups(string_arg)) {
- printf("Could not get groups for user %s\n",
+ d_printf("Could not get groups for user %s\n",
string_arg);
return 1;
}
@@ -747,13 +747,13 @@
BOOL got_error = False;
if (!wbinfo_auth(string_arg)) {
- printf("Could not authenticate user %s with "
+ d_printf("Could not authenticate user %s with "
"plaintext password\n", string_arg);
got_error = True;
}
if (!wbinfo_auth_crap(string_arg)) {
- printf("Could not authenticate user %s with "
+ d_printf("Could not authenticate user %s with "
"challenge/response\n", string_arg);
got_error = True;
}
@@ -765,7 +765,7 @@
case 'p': {
if (!wbinfo_ping()) {
- printf("could not ping winbindd!\n");
+ d_printf("could not ping winbindd!\n");
return 1;
}
break;
@@ -776,7 +776,7 @@
}
break;
default:
- fprintf(stderr, "Invalid option\n");
+ d_fprintf(stderr, "Invalid option\n");
usage();
return 1;
}
More information about the samba-technical
mailing list