ReactOS 0.4.15-dev-7788-g1ad9096
idmap.c
Go to the documentation of this file.
1/* NFSv4.1 client for Windows
2 * Copyright © 2012 The Regents of the University of Michigan
3 *
4 * Olga Kornievskaia <aglo@umich.edu>
5 * Casey Bodley <cbodley@umich.edu>
6 *
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at
10 * your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * without any warranty; without even the implied warranty of merchantability
14 * or fitness for a particular purpose. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 */
21
22#include <windows.h>
23#include <strsafe.h>
24#include <winldap.h>
25#include <stdlib.h> /* for strtoul() */
26#include <errno.h>
27#include <time.h>
28
29#include "idmap.h"
30#include "nfs41_const.h"
31#include "list.h"
32#include "daemon_debug.h"
33
34
35#define IDLVL 2 /* dprintf level for idmap logging */
36
37#define FILTER_LEN 1024
38#define NAME_LEN 32
39#define VAL_LEN 257
40
41
45
47};
48
55
57};
58
59#define ATTR_FLAG(attr) (1 << (attr))
60#define ATTR_ISSET(mask, attr) (((mask) & ATTR_FLAG(attr)) != 0)
61
62
63/* ldap/cache lookups */
67#ifdef __REACTOS__
69#else
71#endif
73 const void *value;
74};
75
76
77#ifndef __REACTOS__
78/* configuration */
79static const char CONFIG_FILENAME[] = "C:\\ReactOS\\System32\\drivers\\etc\\ms-nfs41-idmap.conf";
80#endif
81
83 /* ldap server information */
88
89 /* ldap schema information */
93
94 /* caching configuration */
96};
97
98
103
105 const char *key;
106 const char *def;
108 size_t offset;
109 size_t max_len;
110};
111
112/* helper macros for declaring config_options */
113#define OPT_INT(key,def,field) \
114 { key, def, TYPE_INT, FIELD_OFFSET(struct idmap_config, field), 0 }
115#define OPT_STR(key,def,field,len) \
116 { key, def, TYPE_STR, FIELD_OFFSET(struct idmap_config, field), len }
117#define OPT_CLASS(key,def,index) \
118 { key, def, TYPE_STR, FIELD_OFFSET(struct idmap_config, classes[index]), NAME_LEN }
119#define OPT_ATTR(key,def,index) \
120 { key, def, TYPE_STR, FIELD_OFFSET(struct idmap_config, attributes[index]), NAME_LEN }
121
122/* table of recognized config options, including type and default value */
123static const struct config_option g_options[] = {
124 /* server information */
125 OPT_STR("ldap_hostname", "localhost", hostname, NFS41_HOSTNAME_LEN+1),
126 OPT_INT("ldap_port", "389", port),
127 OPT_INT("ldap_version", "3", version),
128 OPT_INT("ldap_timeout", "0", timeout),
129
130 /* schema information */
131 OPT_STR("ldap_base", "cn=localhost", base, VAL_LEN),
132 OPT_CLASS("ldap_class_users", "user", CLASS_USER),
133 OPT_CLASS("ldap_class_groups", "group", CLASS_GROUP),
134 OPT_ATTR("ldap_attr_username", "cn", ATTR_USER_NAME),
135 OPT_ATTR("ldap_attr_groupname", "cn", ATTR_GROUP_NAME),
136 OPT_ATTR("ldap_attr_gssAuthName", "gssAuthName", ATTR_PRINCIPAL),
137 OPT_ATTR("ldap_attr_uidNumber", "uidNumber", ATTR_UID),
138 OPT_ATTR("ldap_attr_gidNumber", "gidNumber", ATTR_GID),
139
140 /* caching configuration */
141 OPT_INT("cache_ttl", "60", cache_ttl),
142};
143
144
145/* parse each line into key-value pairs
146 * accepts 'key = value' or 'key = "value"',
147 * ignores whitespace anywhere outside the ""s */
149 const char *key, *value;
151};
152
154 char *line,
155 struct config_pair *pair)
156{
157 char *pos = line;
158 int status = NO_ERROR;
159
160 /* terminate at comment */
161 pos = strchr(line, '#');
162 if (pos) *pos = 0;
163
164 /* skip whitespace before key */
165 pos = line;
166 while (isspace(*pos)) pos++;
167 pair->key = pos;
168
169 pos = strchr(pos, '=');
170 if (pos == NULL) {
171 eprintf("missing '='\n");
173 goto out;
174 }
175
176 /* skip whitespace after key */
177 pair->key_len = pos - pair->key;
178 while (pair->key_len && isspace(pair->key[pair->key_len-1]))
179 pair->key_len--;
180
181 if (pair->key_len <= 0) {
182 eprintf("empty key\n");
184 goto out;
185 }
186
187 /* skip whitespace after = */
188 pos++;
189 while (isspace(*pos)) pos++;
190
191 if (*pos == 0) {
192 eprintf("end of line looking for value\n");
194 goto out;
195 }
196
197 if (*pos == '\"') {
198 /* value is between the "s */
199 pair->value = pos + 1;
200 pos = strchr(pair->value, '\"');
201 if (pos == NULL) {
202 eprintf("no matching '\"'\n");
204 goto out;
205 }
206 pair->value_len = pos - pair->value;
207 } else {
208 pair->value = pos;
209 pair->value_len = strlen(pair->value);
210
211 /* skip whitespace after value */
212 while (pair->value_len && isspace(pair->value[pair->value_len-1]))
213 pair->value_len--;
214 }
215
216 /* on success, null terminate the key and value */
217 ((char*)pair->key)[pair->key_len] = 0;
218 ((char*)pair->value)[pair->value_len] = 0;
219out:
220 return status;
221}
222
224 const char *str,
225 UINT *id_out)
226{
227 PCHAR endp;
228 const UINT id = strtoul(str, &endp, 10);
229
230 /* must convert the whole string */
231 if ((endp - str) < (ptrdiff_t)strlen(str))
232 return FALSE;
233
234 /* result must fit in 32 bits */
235 if (id == ULONG_MAX && errno == ERANGE)
236 return FALSE;
237
238 *id_out = id;
239 return TRUE;
240}
241
242/* parse default values from g_options[] into idmap_config */
244 struct idmap_config *config)
245{
246 const struct config_option *option;
247 const int count = ARRAYSIZE(g_options);
248 char *dst;
249 int i, status = NO_ERROR;
250
251 for (i = 0; i < count; i++) {
252 option = &g_options[i];
253 dst = (char*)config + option->offset;
254
255 if (option->type == TYPE_INT) {
256 if (!parse_uint(option->def, (UINT*)dst)) {
258 eprintf("failed to parse default value of %s=\"%s\": "
259 "expected a number\n", option->key, option->def);
260 break;
261 }
262 } else {
263 if (FAILED(StringCchCopyA(dst, option->max_len, option->def))) {
265 eprintf("failed to parse default value of %s=\"%s\": "
266 "buffer overflow > %u\n", option->key, option->def,
267 option->max_len);
268 break;
269 }
270 }
271 }
272 return status;
273}
274
276 const struct config_pair *pair,
277 const struct config_option **option)
278{
279 int i, count = ARRAYSIZE(g_options);
281
282 /* find the config_option by key */
283 for (i = 0; i < count; i++) {
284 if (stricmp(pair->key, g_options[i].key) == 0) {
285 *option = &g_options[i];
287 break;
288 }
289 }
290 return status;
291}
292
293static int config_load(
294 struct idmap_config *config,
295 const char *filename)
296{
297 char buffer[1024], *pos;
298 FILE *file;
299 struct config_pair pair;
300 const struct config_option *option;
301 int line = 0;
302 int status = NO_ERROR;
303
304 /* open the file */
305 file = fopen(filename, "r");
306 if (file == NULL) {
307 eprintf("config_load() failed to open file '%s'\n", filename);
308 goto out;
309 }
310
311 /* read each line */
312 while (fgets(buffer, sizeof(buffer), file)) {
313 line++;
314
315 /* skip whitespace */
316 pos = buffer;
317 while (isspace(*pos)) pos++;
318
319 /* skip comments and empty lines */
320 if (*pos == '#' || *pos == 0)
321 continue;
322
323 /* parse line into a key=value pair */
325 if (status) {
326 eprintf("error on line %d: %s\n", line, buffer);
327 break;
328 }
329
330 /* find the config_option by key */
332 if (status) {
333 eprintf("unrecognized option '%s' on line %d: %s\n",
334 pair.key, line, buffer);
336 break;
337 }
338
339 if (option->type == TYPE_INT) {
340 if (!parse_uint(pair.value, (UINT*)((char*)config + option->offset))) {
342 eprintf("expected a number on line %d: %s=\"%s\"\n",
343 line, pair.key, pair.value);
344 break;
345 }
346 } else {
347 if (FAILED(StringCchCopyNA((char*)config + option->offset,
348 option->max_len, pair.value, pair.value_len))) {
350 eprintf("overflow on line %d: %s=\"%s\"\n",
351 line, pair.key, pair.value);
352 break;
353 }
354 }
355 }
356
357 fclose(file);
358out:
359 return status;
360}
361
362static int config_init(
363 struct idmap_config *config)
364{
365 int status;
366#ifdef __REACTOS__
367 char config_path[MAX_PATH];
368#endif
369
370 /* load default values */
372 if (status) {
373 eprintf("config_defaults() failed with %d\n", status);
374 goto out;
375 }
376
377#ifdef __REACTOS__
378 if (GetSystemDirectoryA(config_path, ARRAYSIZE(config_path)))
379 {
380 StringCchCatA(config_path, ARRAYSIZE(config_path), "\\drivers\\etc\\ms-nfs41-idmap.conf");
381 }
382 else
383 {
385 eprintf("GetSystemDirectoryA failed with %ld\n", GetLastError());
386 goto out;
387 }
388#endif
389
390 /* load configuration from file */
391#ifdef __REACTOS__
392 status = config_load(config, config_path);
393#else
395#endif
396 if (status) {
397#ifdef __REACTOS__
398 eprintf("config_load('%s') failed with %d\n", config_path, status);
399#else
400 eprintf("config_load('%s') failed with %d\n", CONFIG_FILENAME, status);
401#endif
402 goto out;
403 }
404out:
405 return status;
406}
407
408
409/* generic cache */
410typedef struct list_entry* (*entry_alloc_fn)();
411typedef void (*entry_free_fn)(struct list_entry*);
412typedef void (*entry_copy_fn)(struct list_entry*, const struct list_entry*);
413
414struct cache_ops {
418};
419
422 const struct cache_ops *ops;
423 SRWLOCK lock;
424};
425
426
427static void cache_init(
428 struct idmap_cache *cache,
429 const struct cache_ops *ops)
430{
431 list_init(&cache->head);
432 cache->ops = ops;
434}
435
436static void cache_cleanup(
437 struct idmap_cache *cache)
438{
439 struct list_entry *entry, *tmp;
440 list_for_each_tmp(entry, tmp, &cache->head)
441 cache->ops->entry_free(entry);
442 list_init(&cache->head);
443}
444
445static int cache_insert(
446 struct idmap_cache *cache,
447 const struct idmap_lookup *lookup,
448 const struct list_entry *src)
449{
450 struct list_entry *entry;
451 int status = NO_ERROR;
452
454
455 /* search for an existing match */
456 entry = list_search(&cache->head, lookup->value, lookup->compare);
457 if (entry) {
458 /* overwrite the existing entry with the new results */
459 cache->ops->entry_copy(entry, src);
460 goto out;
461 }
462
463 /* initialize a new entry and add it to the list */
464 entry = cache->ops->entry_alloc();
465 if (entry == NULL) {
467 goto out;
468 }
469 cache->ops->entry_copy(entry, src);
470 list_add_head(&cache->head, entry);
471out:
473 return status;
474}
475
476static int cache_lookup(
477 struct idmap_cache *cache,
478 const struct idmap_lookup *lookup,
479 struct list_entry *entry_out)
480{
481 struct list_entry *entry;
483
485
486 entry = list_search(&cache->head, lookup->value, lookup->compare);
487 if (entry) {
488 /* make a copy for use outside of the lock */
489 cache->ops->entry_copy(entry_out, entry);
491 }
492
494 return status;
495}
496
497
498/* user cache */
506};
507
509{
510 struct idmap_user *user = calloc(1, sizeof(struct idmap_user));
511 return user == NULL ? NULL : &user->entry;
512}
513static void user_cache_free(struct list_entry *entry)
514{
516}
517static void user_cache_copy(
518 struct list_entry *lhs,
519 const struct list_entry *rhs)
520{
521 struct idmap_user *dst = list_container(lhs, struct idmap_user, entry);
522 const struct idmap_user *src = list_container(rhs, const struct idmap_user, entry);
523 StringCchCopyA(dst->username, VAL_LEN, src->username);
524 StringCchCopyA(dst->principal, VAL_LEN, src->principal);
525 dst->uid = src->uid;
526 dst->gid = src->gid;
527 dst->last_updated = src->last_updated;
528}
529static const struct cache_ops user_cache_ops = {
533};
534
535
536/* group cache */
542};
543
545{
546 struct idmap_group *group = calloc(1, sizeof(struct idmap_group));
547 return group == NULL ? NULL : &group->entry;
548}
550{
552}
554 struct list_entry *lhs,
555 const struct list_entry *rhs)
556{
557 struct idmap_group *dst = list_container(lhs, struct idmap_group, entry);
558 const struct idmap_group *src = list_container(rhs, const struct idmap_group, entry);
560 dst->gid = src->gid;
561 dst->last_updated = src->last_updated;
562}
563static const struct cache_ops group_cache_ops = {
567};
568
569
570/* ldap context */
576};
577
578
579static int idmap_filter(
580 struct idmap_config *config,
581 const struct idmap_lookup *lookup,
582 char *filter,
583 size_t filter_len)
584{
585 UINT_PTR i;
586 int status = NO_ERROR;
587
588 switch (lookup->type) {
589 case TYPE_INT:
590 i = (UINT_PTR)lookup->value;
591 if (FAILED(StringCchPrintfA(filter, filter_len,
592 "(&(objectClass=%s)(%s=%u))",
593 config->classes[lookup->klass],
594 config->attributes[lookup->attr], (UINT)i))) {
596 eprintf("ldap filter buffer overflow: '%s=%u'\n",
597 config->attributes[lookup->attr], (UINT)i);
598 }
599 break;
600
601 case TYPE_STR:
602 if (FAILED(StringCchPrintfA(filter, filter_len,
603 "(&(objectClass=%s)(%s=%s))",
604 config->classes[lookup->klass],
605 config->attributes[lookup->attr], lookup->value))) {
607 eprintf("ldap filter buffer overflow: '%s=%s'\n",
608 config->attributes[lookup->attr], lookup->value);
609 }
610 break;
611
612 default:
614 break;
615 }
616 return status;
617}
618
620 struct idmap_context *context,
621 const struct idmap_lookup *lookup,
622 const unsigned attributes,
623 const unsigned optional,
624 PCHAR *values[],
625 const int len)
626{
627 char filter[FILTER_LEN];
628 struct idmap_config *config = &context->config;
630 int i, status;
631
632 /* format the ldap filter */
634 if (status)
635 goto out;
636
637 /* send the ldap query */
638 status = ldap_search_st(context->ldap, config->base,
640 if (status) {
641 eprintf("ldap search for '%s' failed with %d: %s\n",
644 goto out;
645 }
646
648 if (entry == NULL) {
650 eprintf("ldap search for '%s' failed with %d: %s\n",
653 goto out;
654 }
655
656 /* fetch the attributes */
657 for (i = 0; i < len; i++) {
658 if (ATTR_ISSET(attributes, i)) {
660 entry, config->attributes[i]);
661
662 /* fail if required attributes are missing */
663 if (values[i] == NULL && !ATTR_ISSET(optional, i)) {
665 eprintf("ldap entry for '%s' missing required "
666 "attribute '%s', returning %d: %s\n",
667 filter, config->attributes[i],
670 goto out;
671 }
672 }
673 }
674out:
675 if (res) ldap_msgfree(res);
676 return status;
677}
678
680 struct idmap_context *context,
681 const struct idmap_lookup *lookup,
682 struct idmap_user *user)
683{
685 const unsigned attributes = ATTR_FLAG(ATTR_USER_NAME)
689 /* principal is optional; we'll cache it if we have it */
690 const unsigned optional = ATTR_FLAG(ATTR_PRINCIPAL);
691 int i, status;
692
693 /* check the user cache for an existing entry */
694 status = cache_lookup(&context->users, lookup, &user->entry);
695 if (status == NO_ERROR) {
696 /* don't return expired entries; query new attributes
697 * and overwrite the entry with cache_insert() */
698 if (time(NULL) - user->last_updated < context->config.cache_ttl)
699 goto out;
700 }
701
702 /* send the query to the ldap server */
705 if (status)
706 goto out_free_values;
707
708 /* parse attributes */
709 if (FAILED(StringCchCopyA(user->username, VAL_LEN,
711 eprintf("ldap attribute %s='%s' longer than %u characters\n",
712 context->config.attributes[ATTR_USER_NAME],
715 goto out_free_values;
716 }
717 if (FAILED(StringCchCopyA(user->principal, VAL_LEN,
719 eprintf("ldap attribute %s='%s' longer than %u characters\n",
720 context->config.attributes[ATTR_PRINCIPAL],
723 goto out_free_values;
724 }
725 if (!parse_uint(*values[ATTR_UID], &user->uid)) {
726 eprintf("failed to parse ldap attribute %s='%s'\n",
727 context->config.attributes[ATTR_UID], *values[ATTR_UID]);
729 goto out_free_values;
730 }
731 if (!parse_uint(*values[ATTR_GID], &user->gid)) {
732 eprintf("failed to parse ldap attribute %s='%s'\n",
733 context->config.attributes[ATTR_GID], *values[ATTR_GID]);
735 goto out_free_values;
736 }
737 user->last_updated = time(NULL);
738
739 if (context->config.cache_ttl) {
740 /* insert the entry into the cache */
741 cache_insert(&context->users, lookup, &user->entry);
742 }
743out_free_values:
744 for (i = 0; i < NUM_ATTRIBUTES; i++)
746out:
747 return status;
748}
749
751 struct idmap_context *context,
752 const struct idmap_lookup *lookup,
753 struct idmap_group *group)
754{
756 const unsigned attributes = ATTR_FLAG(ATTR_GROUP_NAME)
758 int i, status;
759
760 /* check the group cache for an existing entry */
761 status = cache_lookup(&context->groups, lookup, &group->entry);
762 if (status == NO_ERROR) {
763 /* don't return expired entries; query new attributes
764 * and overwrite the entry with cache_insert() */
765 if (time(NULL) - group->last_updated < context->config.cache_ttl)
766 goto out;
767 }
768
769 /* send the query to the ldap server */
772 if (status)
773 goto out_free_values;
774
775 /* parse attributes */
778 eprintf("ldap attribute %s='%s' longer than %u characters\n",
779 context->config.attributes[ATTR_GROUP_NAME],
782 goto out_free_values;
783 }
784 if (!parse_uint(*values[ATTR_GID], &group->gid)) {
785 eprintf("failed to parse ldap attribute %s='%s'\n",
786 context->config.attributes[ATTR_GID], *values[ATTR_GID]);
788 goto out_free_values;
789 }
790 group->last_updated = time(NULL);
791
792 if (context->config.cache_ttl) {
793 /* insert the entry into the cache */
794 cache_insert(&context->groups, lookup, &group->entry);
795 }
796out_free_values:
797 for (i = 0; i < NUM_ATTRIBUTES; i++)
799out:
800 return status;
801}
802
803
804/* public idmap interface */
806 struct idmap_context **context_out)
807{
808 struct idmap_context *context;
809 int status = NO_ERROR;
810
811 context = calloc(1, sizeof(struct idmap_context));
812 if (context == NULL) {
814 goto out;
815 }
816
817 /* initialize the caches */
820
821 /* load ldap configuration from file */
822 status = config_init(&context->config);
823 if (status) {
824 eprintf("config_init() failed with %d\n", status);
825 goto out_err_free;
826 }
827
828 /* initialize ldap and configure options */
829 context->ldap = ldap_init(context->config.hostname, context->config.port);
830 if (context->ldap == NULL) {
832 eprintf("ldap_init(%s) failed with %d: %s\n",
833 context->config.hostname, status, ldap_err2stringA(status));
835 goto out_err_free;
836 }
837
839 (void *)&context->config.version);
840 if (status != LDAP_SUCCESS) {
841 eprintf("ldap_set_option(version=%d) failed with %d\n",
842 context->config.version, status);
844 goto out_err_free;
845 }
846
847 if (context->config.timeout) {
849 (void *)&context->config.timeout);
850 if (status != LDAP_SUCCESS) {
851 eprintf("ldap_set_option(timeout=%d) failed with %d\n",
852 context->config.timeout, status);
854 goto out_err_free;
855 }
856 }
857
858 *context_out = context;
859out:
860 return status;
861
862out_err_free:
864 goto out;
865}
866
868 struct idmap_context *context)
869{
870 /* clean up the connection */
871 if (context->ldap)
872 ldap_unbind(context->ldap);
873
874 cache_cleanup(&context->users);
875 cache_cleanup(&context->groups);
876 free(context);
877}
878
879
880/* username -> uid, gid */
881static int username_cmp(const struct list_entry *list, const void *value)
882{
883 const struct idmap_user *entry = list_container(list,
884 const struct idmap_user, entry);
885 const char *username = (const char*)value;
886 return strcmp(entry->username, username);
887}
888
890 struct idmap_context *context,
891 const char *username,
892 uid_t *uid_out,
893 gid_t *gid_out)
894{
897 struct idmap_user user;
898 int status;
899
900 if (context == NULL)
902
903 dprintf(IDLVL, "--> nfs41_idmap_name_to_ids('%s')\n", username);
904
905 lookup.value = username;
906
907 /* look up the user entry */
909 if (status) {
910 dprintf(IDLVL, "<-- nfs41_idmap_name_to_ids('%s') "
911 "failed with %d\n", username, status);
912 goto out;
913 }
914
915 *uid_out = user.uid;
916 *gid_out = user.gid;
917 dprintf(IDLVL, "<-- nfs41_idmap_name_to_ids('%s') "
918 "returning uid=%u, gid=%u\n", username, user.uid, user.gid);
919out:
920 return status;
921}
922
923/* uid -> username */
924static int uid_cmp(const struct list_entry *list, const void *value)
925{
926 const struct idmap_user *entry = list_container(list,
927 const struct idmap_user, entry);
928 const UINT_PTR uid = (const UINT_PTR)value;
929 return (UINT)uid - entry->uid;
930}
931
933 struct idmap_context *context,
934 uid_t uid,
935 char *name,
936 size_t len)
937{
938 UINT_PTR uidp = uid; /* convert to pointer size to pass as void* */
940 struct idmap_user user;
941 int status;
942
943 dprintf(IDLVL, "--> nfs41_idmap_uid_to_name(%u)\n", uid);
944
945 lookup.value = (const void*)uidp;
946
947 /* look up the user entry */
949 if (status) {
950 dprintf(IDLVL, "<-- nfs41_idmap_uid_to_name(%u) "
951 "failed with %d\n", uid, status);
952 goto out;
953 }
954
955 if (FAILED(StringCchCopyA(name, len, user.username))) {
957 eprintf("username buffer overflow: '%s' > %u\n",
958 user.username, len);
959 goto out;
960 }
961
962 dprintf(IDLVL, "<-- nfs41_idmap_uid_to_name(%u) "
963 "returning '%s'\n", uid, name);
964out:
965 return status;
966}
967
968/* principal -> uid, gid */
969static int principal_cmp(const struct list_entry *list, const void *value)
970{
971 const struct idmap_user *entry = list_container(list,
972 const struct idmap_user, entry);
973 const char *principal = (const char*)value;
974 return strcmp(entry->principal, principal);
975}
976
978 struct idmap_context *context,
979 const char *principal,
980 uid_t *uid_out,
981 gid_t *gid_out)
982{
985 struct idmap_user user;
986 int status;
987
988 dprintf(IDLVL, "--> nfs41_idmap_principal_to_ids('%s')\n", principal);
989
990 lookup.value = principal;
991
992 /* look up the user entry */
994 if (status) {
995 dprintf(IDLVL, "<-- nfs41_idmap_principal_to_ids('%s') "
996 "failed with %d\n", principal, status);
997 goto out;
998 }
999
1000 *uid_out = user.uid;
1001 *gid_out = user.gid;
1002 dprintf(IDLVL, "<-- nfs41_idmap_principal_to_ids('%s') "
1003 "returning uid=%u, gid=%u\n", principal, user.uid, user.gid);
1004out:
1005 return status;
1006}
1007
1008/* group -> gid */
1009static int group_cmp(const struct list_entry *list, const void *value)
1010{
1011 const struct idmap_group *entry = list_container(list,
1012 const struct idmap_group, entry);
1013 const char *group = (const char*)value;
1014 return strcmp(entry->name, group);
1015}
1016
1018 struct idmap_context *context,
1019 const char *name,
1020 gid_t *gid_out)
1021{
1024 struct idmap_group group;
1025 int status;
1026
1027 dprintf(IDLVL, "--> nfs41_idmap_group_to_gid('%s')\n", name);
1028
1029 lookup.value = name;
1030
1031 /* look up the group entry */
1033 if (status) {
1034 dprintf(IDLVL, "<-- nfs41_idmap_group_to_gid('%s') "
1035 "failed with %d\n", name, status);
1036 goto out;
1037 }
1038
1039 *gid_out = group.gid;
1040 dprintf(IDLVL, "<-- nfs41_idmap_group_to_gid('%s') "
1041 "returning %u\n", name, group.gid);
1042out:
1043 return status;
1044}
1045
1046/* gid -> group */
1047static int gid_cmp(const struct list_entry *list, const void *value)
1048{
1049 const struct idmap_group *entry = list_container(list,
1050 const struct idmap_group, entry);
1051 const UINT_PTR gid = (const UINT_PTR)value;
1052 return (UINT)gid - entry->gid;
1053}
1054
1056 struct idmap_context *context,
1057 gid_t gid,
1058 char *name,
1059 size_t len)
1060{
1061 UINT_PTR gidp = gid; /* convert to pointer size to pass as void* */
1063 struct idmap_group group;
1064 int status;
1065
1066 dprintf(IDLVL, "--> nfs41_idmap_gid_to_group(%u)\n", gid);
1067
1068 lookup.value = (const void*)gidp;
1069
1070 /* look up the group entry */
1072 if (status) {
1073 dprintf(IDLVL, "<-- nfs41_idmap_gid_to_group(%u) "
1074 "failed with %d\n", gid, status);
1075 goto out;
1076 }
1077
1080 eprintf("group name buffer overflow: '%s' > %u\n",
1081 group.name, len);
1082 goto out;
1083 }
1084
1085 dprintf(IDLVL, "<-- nfs41_idmap_gid_to_group(%u) "
1086 "returning '%s'\n", gid, name);
1087out:
1088 return status;
1089}
@ optional
Definition: SystemMenu.c:34
#define isspace(c)
Definition: acclib.h:69
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERANGE
Definition: acclib.h:92
char * strchr(const char *String, int ch)
Definition: utclib.c:501
long uid_t
Definition: various.h:8
void user(int argc, const char *argv[])
Definition: cmds.c:1350
char * hostname
Definition: ftp.c:88
#define list_container(entry, type, field)
Definition: list.h:33
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
int(* list_compare_fn)(const struct list_entry *, const void *)
Definition: list.h:100
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static struct list_entry * list_search(const struct list_entry *head, const void *value, list_compare_fn compare)
Definition: list.h:102
static void list_init(struct list_entry *head)
Definition: list.h:51
Definition: list.h:37
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define NO_ERROR
Definition: dderror.h:5
#define free
Definition: debug_ros.c:5
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT32 uint32_t
Definition: types.h:75
UINT gid_t
Definition: types.h:89
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define stricmp(_String1, _String2)
Definition: compat.h:24
#define MAX_PATH
Definition: compat.h:34
static const WCHAR version[]
Definition: asmname.c:66
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2283
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
USHORT port
Definition: uri.c:228
PCHAR CDECL ldap_err2stringA(ULONG err)
Definition: error.c:71
ULONG CDECL LdapMapErrorToWin32(ULONG err)
Definition: error.c:302
ULONG CDECL LdapGetLastError(void)
Definition: error.c:184
static ULONG lookup[16]
Definition: vga.c:38
__kernel_time_t time_t
Definition: linux.h:252
__kernel_ptrdiff_t ptrdiff_t
Definition: linux.h:247
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLsizei GLuint * groups
Definition: glext.h:11113
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLenum GLenum dst
Definition: glext.h:6340
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glext.h:7005
GLboolean GLuint group
Definition: glext.h:11120
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define FILTER_LEN
Definition: idmap.c:37
#define OPT_INT(key, def, field)
Definition: idmap.c:113
ldap_class
Definition: idmap.c:42
@ CLASS_GROUP
Definition: idmap.c:44
@ NUM_CLASSES
Definition: idmap.c:46
@ CLASS_USER
Definition: idmap.c:43
int nfs41_idmap_group_to_gid(struct idmap_context *context, const char *name, gid_t *gid_out)
Definition: idmap.c:1017
static int idmap_query_attrs(struct idmap_context *context, const struct idmap_lookup *lookup, const unsigned attributes, const unsigned optional, PCHAR *values[], const int len)
Definition: idmap.c:619
ldap_attr
Definition: idmap.c:49
@ ATTR_GID
Definition: idmap.c:54
@ ATTR_GROUP_NAME
Definition: idmap.c:51
@ NUM_ATTRIBUTES
Definition: idmap.c:56
@ ATTR_USER_NAME
Definition: idmap.c:50
@ ATTR_PRINCIPAL
Definition: idmap.c:52
@ ATTR_UID
Definition: idmap.c:53
static int cache_insert(struct idmap_cache *cache, const struct idmap_lookup *lookup, const struct list_entry *src)
Definition: idmap.c:445
static void user_cache_free(struct list_entry *entry)
Definition: idmap.c:513
static int config_load(struct idmap_config *config, const char *filename)
Definition: idmap.c:293
static void user_cache_copy(struct list_entry *lhs, const struct list_entry *rhs)
Definition: idmap.c:517
static int uid_cmp(const struct list_entry *list, const void *value)
Definition: idmap.c:924
static const struct cache_ops group_cache_ops
Definition: idmap.c:563
static int idmap_filter(struct idmap_config *config, const struct idmap_lookup *lookup, char *filter, size_t filter_len)
Definition: idmap.c:579
static int config_defaults(struct idmap_config *config)
Definition: idmap.c:243
static int config_find_option(const struct config_pair *pair, const struct config_option **option)
Definition: idmap.c:275
#define IDLVL
Definition: idmap.c:35
static void group_cache_free(struct list_entry *entry)
Definition: idmap.c:549
static int group_cmp(const struct list_entry *list, const void *value)
Definition: idmap.c:1009
#define NAME_LEN
Definition: idmap.c:38
static BOOL parse_uint(const char *str, UINT *id_out)
Definition: idmap.c:223
int nfs41_idmap_name_to_ids(struct idmap_context *context, const char *username, uid_t *uid_out, gid_t *gid_out)
Definition: idmap.c:889
int nfs41_idmap_create(struct idmap_context **context_out)
Definition: idmap.c:805
static int config_parse_pair(char *line, struct config_pair *pair)
Definition: idmap.c:153
void nfs41_idmap_free(struct idmap_context *context)
Definition: idmap.c:867
static int config_init(struct idmap_config *config)
Definition: idmap.c:362
void(* entry_copy_fn)(struct list_entry *, const struct list_entry *)
Definition: idmap.c:412
static int gid_cmp(const struct list_entry *list, const void *value)
Definition: idmap.c:1047
static void group_cache_copy(struct list_entry *lhs, const struct list_entry *rhs)
Definition: idmap.c:553
int nfs41_idmap_uid_to_name(struct idmap_context *context, uid_t uid, char *name, size_t len)
Definition: idmap.c:932
#define ATTR_ISSET(mask, attr)
Definition: idmap.c:60
static void cache_cleanup(struct idmap_cache *cache)
Definition: idmap.c:436
#define VAL_LEN
Definition: idmap.c:39
int nfs41_idmap_gid_to_group(struct idmap_context *context, gid_t gid, char *name, size_t len)
Definition: idmap.c:1055
static int principal_cmp(const struct list_entry *list, const void *value)
Definition: idmap.c:969
int nfs41_idmap_principal_to_ids(struct idmap_context *context, const char *principal, uid_t *uid_out, gid_t *gid_out)
Definition: idmap.c:977
static const char CONFIG_FILENAME[]
Definition: idmap.c:79
static const struct cache_ops user_cache_ops
Definition: idmap.c:529
void(* entry_free_fn)(struct list_entry *)
Definition: idmap.c:411
struct list_entry *(* entry_alloc_fn)()
Definition: idmap.c:410
static int username_cmp(const struct list_entry *list, const void *value)
Definition: idmap.c:881
static int cache_lookup(struct idmap_cache *cache, const struct idmap_lookup *lookup, struct list_entry *entry_out)
Definition: idmap.c:476
static int idmap_lookup_user(struct idmap_context *context, const struct idmap_lookup *lookup, struct idmap_user *user)
Definition: idmap.c:679
#define OPT_STR(key, def, field, len)
Definition: idmap.c:115
static struct list_entry * group_cache_alloc()
Definition: idmap.c:544
static struct list_entry * user_cache_alloc()
Definition: idmap.c:508
static int idmap_lookup_group(struct idmap_context *context, const struct idmap_lookup *lookup, struct idmap_group *group)
Definition: idmap.c:750
#define OPT_ATTR(key, def, index)
Definition: idmap.c:119
#define ATTR_FLAG(attr)
Definition: idmap.c:59
config_type
Definition: idmap.c:99
@ TYPE_STR
Definition: idmap.c:100
@ TYPE_INT
Definition: idmap.c:101
#define OPT_CLASS(key, def, index)
Definition: idmap.c:117
static const struct config_option g_options[]
Definition: idmap.c:123
#define ULONG_MAX
Definition: limits.h:44
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
if(dx< 0)
Definition: linetemp.h:194
__u16 time
Definition: mkdosfs.c:8
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static WCHAR username[]
Definition: url.c:32
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define NFS41_HOSTNAME_LEN
Definition: nfs41_const.h:48
#define dprintf
Definition: regdump.c:33
static FILE * out
Definition: regtests2xml.c:44
#define calloc
Definition: rosglue.h:14
const WCHAR * str
#define errno
Definition: errno.h:18
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
STRSAFEAPI StringCchCopyNA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:230
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
entry_alloc_fn entry_alloc
Definition: idmap.c:415
entry_free_fn entry_free
Definition: idmap.c:416
entry_copy_fn entry_copy
Definition: idmap.c:417
Definition: cache.c:49
HANDLE lock
Definition: cache.c:52
size_t offset
Definition: idmap.c:108
const char * key
Definition: idmap.c:105
enum config_type type
Definition: idmap.c:107
size_t max_len
Definition: idmap.c:109
const char * def
Definition: idmap.c:106
size_t key_len
Definition: idmap.c:150
const char * key
Definition: idmap.c:149
size_t value_len
Definition: idmap.c:150
const char * value
Definition: idmap.c:149
Definition: http.c:7252
char * name
Definition: compiler.c:66
Definition: fci.c:127
struct list_entry head
Definition: idmap.c:421
SRWLOCK lock
Definition: idmap.c:423
const struct cache_ops * ops
Definition: idmap.c:422
UINT timeout
Definition: idmap.c:87
char classes[NUM_CLASSES][NAME_LEN]
Definition: idmap.c:90
UINT port
Definition: idmap.c:85
UINT version
Definition: idmap.c:86
INT cache_ttl
Definition: idmap.c:95
char attributes[NUM_ATTRIBUTES][NAME_LEN]
Definition: idmap.c:91
char hostname[NFS41_HOSTNAME_LEN+1]
Definition: idmap.c:84
LDAP * ldap
Definition: idmap.c:575
struct idmap_cache users
Definition: idmap.c:573
char name[VAL_LEN]
Definition: idmap.c:539
gid_t gid
Definition: idmap.c:540
time_t last_updated
Definition: idmap.c:541
struct list_entry entry
Definition: idmap.c:538
const void * value
Definition: idmap.c:73
list_compare_fn compare
Definition: idmap.c:72
enum ldap_attr attr
Definition: idmap.c:65
enum config_type type
Definition: idmap.c:70
enum ldap_class klass
Definition: idmap.c:66
char username[VAL_LEN]
Definition: idmap.c:501
gid_t gid
Definition: idmap.c:504
time_t last_updated
Definition: idmap.c:505
char principal[VAL_LEN]
Definition: idmap.c:502
struct list_entry entry
Definition: idmap.c:500
uid_t uid
Definition: idmap.c:503
Definition: parser.c:49
Definition: list.h:27
Definition: name.c:39
WCHAR * name
Definition: name.c:42
Definition: getopt.h:109
Definition: _pair.h:47
Definition: ps.c:97
Definition: dhcpd.h:245
static void cache_init()
Definition: svc_auth_des.c:352
int32_t INT
Definition: typedefs.h:58
char * PCHAR
Definition: typedefs.h:51
Definition: pdh_main.c:94
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_NOT_FOUND
Definition: winerror.h:690
#define ldap_init
Definition: winldap.h:638
#define LDAP_NO_SUCH_ATTRIBUTE
Definition: winldap.h:74
WINLDAPAPI ULONG ldap_msgfree(LDAPMessage *)
#define LDAP_SCOPE_SUBTREE
Definition: winldap.h:190
#define LDAP_OPT_TIMELIMIT
Definition: winldap.h:133
#define ldap_value_free
Definition: winldap.h:689
#define ldap_get_values
Definition: winldap.h:670
WINLDAPAPI ULONG ldap_unbind(LDAP *)
WINLDAPAPI PLDAPMessage ldap_first_entry(LDAP *, LDAPMessage *)
#define ldap_search_st
Definition: winldap.h:680
#define LDAP_OPT_PROTOCOL_VERSION
Definition: winldap.h:145
#define LDAP_SUCCESS
Definition: winldap.h:59
#define ldap_set_option
Definition: winldap.h:641
#define LDAP_NO_RESULTS_RETURNED
Definition: winldap.h:114