src/server/daemon/ldap_auth.c

changeset 467
4d038bc6f86e
parent 415
d938228c382e
child 468
73e80eb953f5
equal deleted inserted replaced
466:019c22775f7c 467:4d038bc6f86e
37 37
38 #include <cx/utils.h> 38 #include <cx/utils.h>
39 #include <cx/hash_map.h> 39 #include <cx/hash_map.h>
40 40
41 #include "ldap_auth.h" 41 #include "ldap_auth.h"
42 42 #include "ldap_resource.h"
43 static void ws_ldap_close(LDAP *ldap) { 43
44 #ifdef SOLARIS 44
45 ldap_unbind(ldap); 45 static LDAPConfig ws_ldap_default_config = {
46 #else 46 NULL, // resource
47 ldap_unbind_ext_s(ldap, NULL, NULL); 47 NULL, // basedn
48 #endif 48 NULL, // binddn
49 } 49 NULL, // bindpw
50 50 "(&(objectclass=inetorgperson)(!(cn=%s)(uid=%s)))", // userSearchFilter
51 AuthDB* create_ldap_authdb(ServerConfiguration *cfg, const char *name, LDAPConfig *conf) { 51 {"uid"}, // uidAttributes
52 1, // numUidAttributes
53 "(&(|(objectclass=groupOfNames)(objectclass=groupOfUniqueNames))(cn=%s))", // groupSearchFilter
54 {"member", "uniqueMember"}, // memberAttributes
55 2, // numMemberAttributes
56 WS_LDAP_GROUP_MEMBER_DN, // groupMemberType
57 TRUE, // enableGroups
58 FALSE // userNameIsDN
59 };
60
61 // TODO
62 static LDAPConfig ws_ldap_ad_config = {
63 NULL, // resource
64 NULL, // basedn
65 NULL, // binddn
66 NULL, // bindpw
67 "(&(objectclass=inetorgperson)(!(cn=%s)(uid=%s)))", // userSearchFilter
68 {"uid"}, // uidAttributes
69 1, // numUidAttributes
70 "", // groupSearchFilter
71 {"uniqueMember", "member"}, // memberAttributes
72 2, // numMemberAttributes
73 WS_LDAP_GROUP_MEMBER_DN, // groupMemberType
74 TRUE, // enableGroups
75 FALSE // userNameIsDN
76 };
77
78 static LDAPConfig ws_ldap_posix_config = {
79 NULL, // resource
80 NULL, // basedn
81 NULL, // binddn
82 NULL, // bindpw
83 "(&(objectclass=posixAccount)(uid=%s))", // userSearchFilter
84 {"uid"}, // uidAttributes
85 1, // numUidAttributes
86 "(&(objectclass=posixGroup)(cn=%s))", // groupSearchFilter
87 {"memberUid"}, // memberAttributes
88 1, // numMemberAttributes
89 WS_LDAP_GROUP_MEMBER_UID, // groupMemberType
90 TRUE, // enableGroups
91 FALSE // userNameIsDN
92 };
93
94 AuthDB* create_ldap_authdb(ServerConfiguration *cfg, const char *name, ConfigNode *node) {
52 LDAPAuthDB *authdb = cxMalloc(cfg->a, sizeof(LDAPAuthDB)); 95 LDAPAuthDB *authdb = cxMalloc(cfg->a, sizeof(LDAPAuthDB));
96 if(!authdb) {
97 return NULL;
98 }
53 authdb->authdb.name = pool_strdup(cfg->pool, name); 99 authdb->authdb.name = pool_strdup(cfg->pool, name);
100 if(!authdb->authdb.name) {
101 return NULL;
102 }
54 authdb->authdb.get_user = ldap_get_user; 103 authdb->authdb.get_user = ldap_get_user;
55 authdb->authdb.use_cache = 1; 104 authdb->authdb.use_cache = 1;
56 authdb->config = *conf; 105
57 106 // initialize default ldap config
58 if (!authdb->config.usersearch) { 107 cxstring dirtype = serverconfig_object_directive_value(node, cx_str("DirectoryType"));
59 authdb->config.usersearch = "uid"; 108 LDAPConfig *default_config;
60 } 109 if(!dirtype.ptr) {
61 if (!authdb->config.groupsearch) { 110 default_config = &ws_ldap_default_config;
62 authdb->config.groupsearch = "uniquemember"; 111 } else if(!cx_strcmp(dirtype, cx_str("ldap"))) {
112 default_config = &ws_ldap_default_config;
113 } else if(!cx_strcmp(dirtype, cx_str("posix"))) {
114 default_config = &ws_ldap_posix_config;
115 } else if(!cx_strcmp(dirtype, cx_str("ad"))) {
116 default_config = &ws_ldap_ad_config;
117 } else {
118 log_ereport(LOG_FAILURE, "cannot create ldap authdb %s: unknown directory type %s", name, dirtype.ptr);
119 }
120 memcpy(&authdb->config, default_config, sizeof(LDAPConfig));
121
122 // custom config
123 cxstring resource = serverconfig_object_directive_value(node, cx_str("Resource"));
124 cxstring basedn = serverconfig_object_directive_value(node, cx_str("Basedn"));
125 cxstring binddn = serverconfig_object_directive_value(node, cx_str("Binddn"));
126 cxstring bindpw = serverconfig_object_directive_value(node, cx_str("Bindpw"));
127 cxstring usersearchfilter = serverconfig_object_directive_value(node, cx_str("UserSearchFilter"));
128 // TODO ...
129
130 if(!resource.ptr) {
131 // TODO: create resource pool
132 } else {
133 authdb->config.resource = resource.ptr;
63 } 134 }
64 135
65 // initialize group cache 136 // initialize group cache
66 authdb->groups.first = NULL; 137 authdb->groups.first = NULL;
67 authdb->groups.last = NULL; 138 authdb->groups.last = NULL;
68 authdb->groups.map = cxHashMapCreate(cfg->a, 32); 139 authdb->groups.map = cxHashMapCreate(cfg->a, 32);
140 if(!authdb->groups.map) {
141 return NULL;
142 }
69 143
70 return (AuthDB*) authdb; 144 return (AuthDB*) authdb;
71 } 145 }
72 146
73 LDAP* get_ldap_session(LDAPAuthDB *authdb) { 147 LDAP* get_ldap_session(Session *sn, Request *rq, LDAPAuthDB *authdb) {
74 LDAPConfig *config = &authdb->config; 148 ResourceData *res = resourcepool_lookup(sn, rq, authdb->config.resource, 0);
75 LDAP *ld = NULL; 149 if(!res) {
76 150 log_ereport(LOG_FAILURE, "AuthDB %s: cannot get resource %s", authdb->authdb.name, authdb->config.resource);
77 #ifdef SOLARIS 151 return NULL;
78 ld = ldap_init(config->hostname, config->port); 152 }
79 #else 153
80 char *ldap_uri = NULL; 154 LDAP *ldap = res->data;
81 asprintf(&ldap_uri, "ldap://%s:%d", config->hostname, config->port); 155
82 int init_ret = ldap_initialize(&ld, ldap_uri); 156 if(authdb->config.binddn) {
83 free(ldap_uri); 157 struct berval *server_cred;
84 if(init_ret) { 158 int r = ws_ldap_bind(ldap, authdb->config.binddn, authdb->config.bindpw, &server_cred);
85 fprintf(stderr, "ldap_initialize failed\n"); 159 if(r != LDAP_SUCCESS) {
86 } 160 log_ereport(LOG_FAILURE, "AuthDB %s: bind to %s failed: %s", authdb->config.binddn, ldap_err2string(r));
87 #endif 161 resourcepool_free(sn, rq, res);
88 if(!ld) { 162 return NULL;
89 return NULL; 163 }
90 } 164 }
91 165
92 int ldapv = LDAP_VERSION3; 166 return ldap;
93 ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapv); 167 }
94 168
95 // admin bind 169 User* ldap_get_user(AuthDB *db, Session *sn, Request *rq, const char *username) {
96 struct berval cred;
97 cred.bv_val = config->bindpw;
98 cred.bv_len = strlen(config->bindpw);
99 struct berval *server_cred;
100 int r = ldap_sasl_bind_s(
101 ld,
102 config->binddn,
103 LDAP_SASL_SIMPLE,
104 &cred,
105 NULL,
106 NULL,
107 &server_cred);
108 if (r != LDAP_SUCCESS) {
109 ws_ldap_close(ld);
110 fprintf(stderr, "ldap_simple_bind_s failed: %s\n", ldap_err2string(r));
111 return NULL;
112 }
113
114 return ld;
115 }
116
117 User* ldap_get_user(AuthDB *db, const char *username) {
118 LDAPAuthDB *authdb = (LDAPAuthDB*) db; 170 LDAPAuthDB *authdb = (LDAPAuthDB*) db;
119 LDAPConfig *config = &authdb->config; 171 LDAPConfig *config = &authdb->config;
120 172
121 LDAP *ld = get_ldap_session(authdb); 173 LDAP *ld = get_ldap_session(sn, rq, authdb);
122 if (ld == NULL) { 174 if (ld == NULL) {
123 fprintf(stderr, "ldap_init failed\n"); 175 fprintf(stderr, "ldap_init failed\n");
124 return NULL; 176 return NULL;
125 } 177 }
126 178
154 return NULL; 206 return NULL;
155 } 207 }
156 208
157 LDAPMessage *msg = ldap_first_entry(ld, result); 209 LDAPMessage *msg = ldap_first_entry(ld, result);
158 if (msg) { 210 if (msg) {
159 LDAPUser *user = malloc(sizeof(LDAPUser)); 211 LDAPUser *user = pool_malloc(sn->pool, sizeof(LDAPUser));
160 if (user != NULL) { 212 if (user != NULL) {
161 user->authdb = authdb; 213 user->authdb = authdb;
162 user->user.verify_password = ldap_user_verify_password; 214 user->user.verify_password = ldap_user_verify_password;
163 user->user.check_group = ldap_user_check_group; 215 user->user.check_group = ldap_user_check_group;
164 user->user.free = ldap_user_free; 216 user->user.free = ldap_user_free;
165 user->user.name = (char*)username; // must not be freed TODO: maybe copy 217 user->user.name = pool_strdup(sn->pool, username);
218 user->sn = sn;
219 user->rq = rq;
166 220
167 // TODO: get uid/gid from ldap 221 // TODO: get uid/gid from ldap
168 user->user.uid = -1; 222 user->user.uid = -1;
169 user->user.gid = -1; 223 user->user.gid = -1;
170 224
179 233
180 ws_ldap_close(ld); 234 ws_ldap_close(ld);
181 return NULL; 235 return NULL;
182 } 236 }
183 237
184 LDAPGroup* ldap_get_group(LDAPAuthDB *authdb, const char *group) { 238 LDAPGroup* ldap_get_group(Session *sn, Request *rq, LDAPAuthDB *authdb, const char *group) {
185 printf("ldap_get_group: %s\n", group); 239 printf("ldap_get_group: %s\n", group);
186 240
187 LDAPConfig *config = &authdb->config; 241 LDAPConfig *config = &authdb->config;
188 242
189 LDAP *ld = get_ldap_session(authdb); 243 LDAP *ld = get_ldap_session(sn, rq, authdb);
190 if (ld == NULL) { 244 if (ld == NULL) {
191 fprintf(stderr, "ldap_init failed\n"); 245 fprintf(stderr, "ldap_init failed\n");
192 return NULL; 246 return NULL;
193 } 247 }
194 248
300 int ldap_user_check_group(User *u, const char *group_str) { 354 int ldap_user_check_group(User *u, const char *group_str) {
301 LDAPUser *user = (LDAPUser*)u; 355 LDAPUser *user = (LDAPUser*)u;
302 356
303 int ret = 0; 357 int ret = 0;
304 358
305 LDAPGroup *group = ldap_get_group(user->authdb, group_str); 359 LDAPGroup *group = ldap_get_group(user->sn, user->rq, user->authdb, group_str);
306 for(int i=0;i<group->nmembers;i++) { 360 for(int i=0;i<group->nmembers;i++) {
307 char *member = group->members[i].name; 361 char *member = group->members[i].name;
308 if(!strcmp(member, u->name)) { 362 if(!strcmp(member, u->name)) {
309 printf("is member\n"); 363 printf("is member\n");
310 ret = 1; 364 ret = 1;

mercurial