]>
Commit | Line | Data |
---|---|---|
212019fb | 1 | diff -ru openssh-3.6.1p1/auth2-pubkey.c openssh-3.6.1p1-ldappubkey/auth2-pubkey.c |
2 | --- openssh-3.6.1p1/auth2-pubkey.c Thu Jun 6 22:27:56 2002 | |
3 | +++ openssh-3.6.1p1-ldappubkey/auth2-pubkey.c Thu Apr 17 11:53:03 2003 | |
4 | @@ -174,12 +174,46 @@ | |
5 | struct stat st; | |
6 | Key *found; | |
7 | char *fp; | |
8 | +#ifdef WITH_LDAP_PUBKEY | |
9 | + lh host; | |
10 | +#endif | |
11 | ||
12 | if (pw == NULL) | |
13 | return 0; | |
14 | ||
15 | /* Temporarily use the user's uid. */ | |
16 | temporarily_use_uid(pw); | |
17 | +#ifdef WITH_LDAP_PUBKEY | |
18 | + found_key = 0; | |
19 | + /* allocate a new key type */ | |
20 | + found = key_new(key->type); | |
21 | + | |
22 | + /* first check if the options is enabled, then try.. */ | |
23 | + debug("trying LDAP first uid=%s",pw->pw_name); | |
24 | + | |
25 | + /* lets add it */ | |
26 | + host.url = options.myldap_opt.ldap_server; | |
27 | + host.binddn = options.myldap_opt.binddn; | |
28 | + host.bindpw = options.myldap_opt.bindpw; | |
29 | + host.mgroup = options.myldap_opt.mgroup; | |
30 | + | |
31 | + if(options.myldap_opt.pubkey_from_ldap | |
32 | + &&(key_ldap_read(found,pw->pw_name,&host) != 1)) { | |
33 | + debug2("LDAP pubkey failed!!!"); | |
34 | + debug2("URL: %s !!",options.myldap_opt.ldap_server); | |
35 | + } | |
36 | + | |
37 | + if (key_equal(found,key)) { | |
38 | + found_key = 1; | |
39 | + debug("matching key found on LDAP, line %lu",linenum); | |
40 | + fp = key_fingerprint(found,SSH_FP_MD5, SSH_FP_HEX); | |
41 | + verbose("Found matching %s key: %s",key_type(found),fp); | |
42 | + xfree(fp); | |
43 | + restore_uid(); | |
44 | + key_free(found); | |
45 | + return found_key; | |
46 | + } | |
47 | +#endif | |
48 | ||
49 | debug("trying public key file %s", file); | |
50 | ||
51 | @@ -189,6 +223,7 @@ | |
52 | restore_uid(); | |
53 | return 0; | |
54 | } | |
55 | + | |
56 | /* Open the file containing the authorized keys. */ | |
57 | f = fopen(file, "r"); | |
58 | if (!f) { | |
59 | @@ -196,6 +231,7 @@ | |
60 | restore_uid(); | |
61 | return 0; | |
62 | } | |
63 | + | |
64 | if (options.strict_modes && | |
65 | secure_filename(f, file, pw, line, sizeof(line)) != 0) { | |
66 | fclose(f); | |
67 | @@ -204,8 +240,11 @@ | |
68 | return 0; | |
69 | } | |
70 | ||
71 | + /* | |
72 | found_key = 0; | |
73 | found = key_new(key->type); | |
74 | + old place of found_key = 0; | |
75 | + */ | |
76 | ||
77 | while (fgets(line, sizeof(line), f)) { | |
78 | char *cp, *options = NULL; | |
79 | diff -ru openssh-3.6.1p1/key.c openssh-3.6.1p1-ldappubkey/key.c | |
80 | --- openssh-3.6.1p1/key.c Mon Feb 24 02:01:41 2003 | |
81 | +++ openssh-3.6.1p1-ldappubkey/key.c Thu Apr 17 11:48:00 2003 | |
82 | @@ -36,6 +36,25 @@ | |
83 | ||
84 | #include <openssl/evp.h> | |
85 | ||
86 | +#ifdef WITH_LDAP_PUBKEY | |
87 | +#include <ldap.h> | |
88 | +#include <lber.h> | |
89 | + | |
90 | +#define PORT LDAP_PORT | |
91 | +#define LINEMAX 1024 | |
92 | +/* | |
93 | + * defined in core.schema, this is a temporary objectclass which can be | |
94 | + * used since i m waiting for pkix schema and pubKey attribute (binary as well | |
95 | + * so minor changes for this patch), there will be an update about this ;) | |
96 | + * the following defs were for test purposes only | |
97 | + * i'm still keeping objectclass=strongAuthenticationuser because of the purpose | |
98 | + * this patch, and wrongly using cn for each user to store group includes | |
99 | + * refere to the README for a better understanding of this. | |
100 | + */ | |
101 | +#define OBJCLASS "objectclass=strongAuthenticationUser" | |
102 | +#define BASE_REQ "ou=users,dc=foobar,dc=net" | |
103 | +#endif | |
104 | + | |
105 | #include "xmalloc.h" | |
106 | #include "key.h" | |
107 | #include "rsa.h" | |
108 | @@ -372,6 +391,217 @@ | |
109 | OPENSSL_free(buf); | |
110 | return 1; | |
111 | } | |
112 | + | |
113 | +#ifdef WITH_LDAP_PUBKEY | |
114 | +/* returns 1 ok, -1 error */ | |
115 | +int | |
116 | +/* key_ldap_read(Key *ret, char *uid, char *url, char *binddn, char *bindpw) */ | |
117 | +key_ldap_read(Key *ret, char *uid, lh *host) | |
118 | +{ | |
119 | + Key *k; | |
120 | + LDAP *ld; | |
121 | + LDAPMessage *res,*e; | |
122 | + LDAPURLDesc *urlstruct; | |
123 | + char *a,*urlssl,objbuf[LINEMAX]; | |
124 | + struct berval **vals; | |
125 | + BerElement *ptr; | |
126 | + int version, rc, j, i, success = -1, ssl_size = 0; | |
127 | + | |
128 | + /* version to 3 */ | |
129 | + version = LDAP_VERSION3; | |
130 | + | |
131 | + /* url based ldap://hostport/dn[?attrs[?scope[?filter[?exts]]]] */ | |
132 | + rc = ldap_is_ldap_url(host->url); | |
133 | + if (rc < 0) { | |
134 | + error("key_ldap_read: ldap_is_ldap_url() -> ldap is not an url"); | |
135 | + | |
136 | + success = -1; | |
137 | + return success; | |
138 | + } | |
139 | + | |
140 | + rc = ldap_url_parse(host->url,&urlstruct); | |
141 | + if (rc) { | |
142 | + error("key_ldap_read: ldap_url_parse() -> ldap couldn't be parsed"); | |
143 | + | |
144 | + success = -1; | |
145 | + return success; | |
146 | + } | |
147 | + | |
148 | + ssl_size = strlen(urlstruct->lud_scheme)+strlen(urlstruct->lud_host)+10; | |
149 | + | |
150 | + urlssl = (char *) malloc( ssl_size * sizeof(char) ); | |
151 | + if (!urlssl) { | |
152 | + error("key_ldap_read: malloc()"); | |
153 | + | |
154 | + /* free what has been allocated */ | |
155 | + ldap_free_urldesc(urlstruct); | |
156 | + | |
157 | + success = -1; | |
158 | + return success; | |
159 | + } | |
160 | + memset(urlssl,0,ssl_size); | |
161 | + snprintf(urlssl,ssl_size,"%s://%s:%d",urlstruct->lud_scheme,urlstruct->lud_host,urlstruct->lud_port); | |
162 | + | |
163 | + /* open ldap connection */ | |
164 | + ld = ldap_init(urlstruct->lud_host,urlstruct->lud_port); | |
165 | + if(!ld) { | |
166 | + error("key_ldap_read: ldap_init()"); | |
167 | + | |
168 | + /* free what has been allocated */ | |
169 | + free(urlssl); | |
170 | + ldap_free_urldesc(urlstruct); | |
171 | + | |
172 | + success = -1; | |
173 | + return success; | |
174 | + } | |
175 | + | |
176 | + /* setting V3 proto otherwise TLS impossible */ | |
177 | + if (ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,&version) != LDAP_OPT_SUCCESS) { | |
178 | + error("key_ldap_read: ldap couldn't set version for TLS/SSL"); | |
179 | + | |
180 | + /* free what has been allocated */ | |
181 | + free(urlssl); | |
182 | + ldap_free_urldesc(urlstruct); | |
183 | + | |
184 | + success = -1; | |
185 | + return success; | |
186 | + } | |
187 | + /* HERE CHOOSE SSL/TLS use the scheme and look for the magic 's' ;) */ | |
188 | + if (urlstruct->lud_scheme[strlen(urlstruct->lud_scheme)-1] == 's') { | |
189 | + if (ldap_initialize(&ld, urlssl) != LDAP_SUCCESS) { | |
190 | + error("key_ldap_read: ldap_initialize()"); | |
191 | + | |
192 | + /* free what has been allocated */ | |
193 | + free(urlssl); | |
194 | + ldap_free_urldesc(urlstruct); | |
195 | + | |
196 | + success = -1; | |
197 | + return success; | |
198 | + } | |
199 | + } else { | |
200 | + if ( (ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS)) { | |
201 | + ldap_perror( ld, "key_ldap_read: (TLS) ldap_start_tls" ); | |
202 | + /* recover to normal connection */ | |
203 | + ld = ldap_init(urlstruct->lud_host,urlstruct->lud_port); | |
204 | + if(!ld) { | |
205 | + error("key_ldap_read: ldap_init()"); | |
206 | + | |
207 | + /* free what has been allocated */ | |
208 | + free(urlssl); | |
209 | + ldap_free_urldesc(urlstruct); | |
210 | + | |
211 | + success = -1; | |
212 | + return success; | |
213 | + } | |
214 | + /* use_ssl=1; */ | |
215 | + } | |
216 | + } | |
217 | + | |
218 | + /* anonymous bind pubkey can be retrieved by anybody */ | |
219 | + if (ldap_simple_bind_s(ld,host->binddn,host->bindpw) != LDAP_SUCCESS) { | |
220 | + error("key_ldap_read: ldap_simple_bind_s()"); | |
221 | + | |
222 | + /* free what has been allocated */ | |
223 | + free(urlssl); | |
224 | + ldap_free_urldesc(urlstruct); | |
225 | + | |
226 | + success = -1; | |
227 | + return success; | |
228 | + } | |
229 | + | |
230 | + /* start ldap search */ | |
231 | + if (!uid) | |
232 | + return success; | |
233 | + | |
234 | + /* | |
235 | + * | |
236 | + * The user need to have posixAccount & strongAuthenticationuser attributes | |
237 | + * to accept the challenge. | |
238 | + * posixAccount & strongAuthenticationuser + uid is member of configured group. | |
239 | + * ldap user entries MUST respect our standard description. | |
240 | + * objectclass still hardcoded, hope to change this soon . | |
241 | + * | |
242 | + */ | |
243 | + if (host->mgroup) | |
244 | + snprintf(objbuf,LINEMAX,"(&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(&(cn=*%s*)(uid=%s)))",host->mgroup,uid); | |
245 | + else | |
246 | + snprintf(objbuf,LINEMAX,"(&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(uid=%s))",uid); | |
247 | + | |
248 | + /* New filter group inclusive depend on the configuration */ | |
249 | + /* (&(objectclass=posixAccount)(objectclass=strongAuthenticationUser)(&(cn=*groupname*)(uid=eau))) */ | |
250 | + | |
251 | + ldap_search_s(ld,urlstruct->lud_dn,LDAP_SCOPE_SUBTREE,objbuf,NULL,0,&res); | |
252 | + i = ldap_count_entries(ld,res); | |
253 | + | |
254 | + for(e=ldap_first_entry(ld,res); e != NULL; e=ldap_next_entry(ld,e)) { | |
255 | + ldap_get_dn(ld,e); | |
256 | + for(a=ldap_first_attribute(ld,e,&ptr);a!=NULL;a=ldap_next_attribute(ld,e,ptr)) | |
257 | + { | |
258 | + if(strncmp(a,"userCertificate",15) == 0) { | |
259 | + vals=ldap_get_values_len(ld,e,a); | |
260 | + for(j = 0; vals[j] != NULL; j++) { | |
261 | + /* value is here :) vals[j] */ | |
262 | + k = key_from_blob((unsigned char *)vals[j]->bv_val,(int)vals[j]->bv_len); | |
263 | + | |
264 | + if (!k) { | |
265 | + error("key_read: key_from_blob LDAP failed"); | |
266 | + | |
267 | + ldap_value_free_len(vals); | |
268 | + ldap_free_urldesc(urlstruct); | |
269 | + free(urlssl); | |
270 | + | |
271 | + return (-1); | |
272 | + } | |
273 | + | |
274 | + /* i dont have type ?!?!?! */ | |
275 | + if (k->type != KEY_DSA) { | |
276 | + error("key_read: type mismatch: encoding error"); | |
277 | + | |
278 | + ldap_value_free_len(vals); | |
279 | + ldap_free_urldesc(urlstruct); | |
280 | + free(urlssl); | |
281 | + key_free(k); | |
282 | + | |
283 | + return (-1); | |
284 | + } | |
285 | + | |
286 | + if (ret->type == KEY_RSA) { | |
287 | + error("LDAP doesnt handle RSA keys yet"); | |
288 | + | |
289 | + /* freeing everything */ | |
290 | + ldap_value_free_len(vals); | |
291 | + ldap_free_urldesc(urlstruct); | |
292 | + free(urlssl); | |
293 | + key_free(k); | |
294 | + | |
295 | + return (-1); | |
296 | + } else { | |
297 | + if (ret->dsa != NULL) | |
298 | + DSA_free(ret->dsa); | |
299 | + ret->dsa = k->dsa; | |
300 | + k->dsa = NULL; | |
301 | + DSA_print_fp(stderr,ret->dsa,8); | |
302 | + | |
303 | + /* freeing everything */ | |
304 | + ldap_value_free_len(vals); | |
305 | + ldap_free_urldesc(urlstruct); | |
306 | + free(urlssl); | |
307 | + key_free(k); | |
308 | + | |
309 | + success = 1; | |
310 | + return success; | |
311 | + } | |
312 | + } | |
313 | + ldap_value_free_len(vals); | |
314 | + key_free(k); | |
315 | + } | |
316 | + } | |
317 | + } | |
318 | + ldap_free_urldesc(urlstruct); | |
319 | + free(urlssl); | |
320 | + return success; | |
321 | +} | |
322 | +#endif | |
323 | ||
324 | /* returns 1 ok, -1 error */ | |
325 | int | |
326 | diff -ru openssh-3.6.1p1/key.h openssh-3.6.1p1-ldappubkey/key.h | |
327 | --- openssh-3.6.1p1/key.h Mon Feb 24 02:01:41 2003 | |
328 | +++ openssh-3.6.1p1-ldappubkey/key.h Thu Apr 17 11:48:05 2003 | |
329 | @@ -64,6 +64,18 @@ | |
330 | char *key_type(Key *); | |
331 | int key_write(Key *, FILE *); | |
332 | int key_read(Key *, char **); | |
333 | +#ifdef WITH_LDAP_PUBKEY | |
334 | +/* next step is to handle fallback on ldap servers */ | |
335 | +typedef struct ldaphost { | |
336 | + char *url; /* LDAP infos in URL format */ | |
337 | + char *binddn; /* bind DN */ | |
338 | + char *bindpw; /* obvious :> */ | |
339 | + char *mgroup; /* server group name */ | |
340 | + struct ldaphost *next; | |
341 | +} lh; | |
342 | + | |
343 | +int key_ldap_read(Key *, char *, lh *); | |
344 | +#endif | |
345 | u_int key_size(Key *); | |
346 | ||
347 | Key *key_generate(int, u_int); | |
348 | diff -ru openssh-3.6.1p1/servconf.c openssh-3.6.1p1-ldappubkey/servconf.c | |
349 | --- openssh-3.6.1p1/servconf.c Mon Feb 24 02:04:34 2003 | |
350 | +++ openssh-3.6.1p1-ldappubkey/servconf.c Thu Apr 17 12:04:42 2003 | |
351 | @@ -123,6 +123,13 @@ | |
352 | options->client_alive_count_max = -1; | |
353 | options->authorized_keys_file = NULL; | |
354 | options->authorized_keys_file2 = NULL; | |
355 | +#ifdef WITH_LDAP_PUBKEY | |
356 | + options->myldap_opt.pubkey_from_ldap = -1; | |
357 | + options->myldap_opt.ldap_server = NULL; | |
358 | + options->myldap_opt.binddn = NULL; | |
359 | + options->myldap_opt.bindpw = NULL; | |
360 | + options->myldap_opt.mgroup = NULL; | |
361 | +#endif | |
362 | ||
363 | /* Needs to be accessable in many places */ | |
364 | use_privsep = -1; | |
365 | @@ -255,6 +262,18 @@ | |
366 | } | |
367 | if (options->authorized_keys_file == NULL) | |
368 | options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; | |
369 | +#ifdef WITH_LDAP_PUBKEY | |
370 | + if (options->myldap_opt.pubkey_from_ldap == -1) | |
371 | + options->myldap_opt.pubkey_from_ldap = 0; | |
372 | + if (options->myldap_opt.ldap_server == NULL) | |
373 | + options->myldap_opt.ldap_server = _DEFAULT_LDAP_PUBKEY_SERVER; | |
374 | + if (options->myldap_opt.binddn == NULL) | |
375 | + options->myldap_opt.binddn = _DEFAULT_BINDDN; | |
376 | + if (options->myldap_opt.bindpw == NULL) | |
377 | + options->myldap_opt.bindpw = _DEFAULT_BINDPW; | |
378 | + if (options->myldap_opt.mgroup == NULL) | |
379 | + options->myldap_opt.mgroup = _DEFAULT_MGROUP; | |
380 | +#endif | |
381 | ||
382 | /* Turn privilege separation on by default */ | |
383 | if (use_privsep == -1) | |
384 | @@ -303,6 +322,9 @@ | |
385 | sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, | |
386 | sUsePrivilegeSeparation, | |
387 | sDeprecated | |
388 | +#ifdef WITH_LDAP_PUBKEY | |
389 | + ,sPubkey_from_ldap, sLdap_server, sBinddn, sBindpw, sMgroup | |
390 | +#endif | |
391 | } ServerOpCodes; | |
392 | ||
393 | /* Textual representation of the tokens. */ | |
394 | @@ -379,6 +401,13 @@ | |
395 | { "clientalivecountmax", sClientAliveCountMax }, | |
396 | { "authorizedkeysfile", sAuthorizedKeysFile }, | |
397 | { "authorizedkeysfile2", sAuthorizedKeysFile2 }, | |
398 | +#ifdef WITH_LDAP_PUBKEY | |
399 | + { "pubkeyfromldap", sPubkey_from_ldap }, | |
400 | + { "ldapserver", sLdap_server }, | |
401 | + { "binddn", sBinddn }, | |
402 | + { "bindpw", sBindpw }, | |
403 | + { "mygroup", sMgroup }, | |
404 | +#endif | |
405 | { "useprivilegeseparation", sUsePrivilegeSeparation}, | |
406 | { NULL, sBadOption } | |
407 | }; | |
408 | @@ -915,6 +944,54 @@ | |
409 | while (arg) | |
410 | arg = strdelim(&cp); | |
411 | break; | |
412 | +#ifdef WITH_LDAP_PUBKEY | |
413 | + case sPubkey_from_ldap: | |
414 | + intptr = &options->myldap_opt.pubkey_from_ldap; | |
415 | + goto parse_flag; | |
416 | + case sLdap_server: | |
417 | + /* arg = strdelim(&cp); */ | |
418 | + p = line; | |
419 | + while(*p++); | |
420 | + arg = p; | |
421 | + if (!arg || *arg == '\0') | |
422 | + fatal("%s line %d: missing ldap server",filename,linenum); | |
423 | + arg[strlen(arg)-1] = '\0'; | |
424 | + options->myldap_opt.ldap_server=xstrdup(arg); | |
425 | + memset(arg,0,strlen(arg)); | |
426 | + break; | |
427 | + case sBinddn: | |
428 | + /* arg = strdelim(&cp); */ | |
429 | + p = line; | |
430 | + while(*p++); | |
431 | + arg = p; | |
432 | + if (!arg || *arg == '\0') | |
433 | + fatal("%s line %d: missing binddn",filename,linenum); | |
434 | + arg[strlen(arg)-1] = '\0'; | |
435 | + options->myldap_opt.binddn = xstrdup(arg); | |
436 | + memset(arg,0,strlen(arg)); | |
437 | + break; | |
438 | + case sBindpw: | |
439 | + /* arg = strdelim(&cp); */ | |
440 | + p = line; | |
441 | + while(*p++); | |
442 | + arg = p; | |
443 | + if (!arg || *arg == '\0') | |
444 | + fatal("%s line %d: missing bindpw",filename,linenum); | |
445 | + arg[strlen(arg)-1] = '\0'; | |
446 | + options->myldap_opt.bindpw=xstrdup(arg); | |
447 | + memset(arg,0,strlen(arg)); | |
448 | + break; | |
449 | + case sMgroup: | |
450 | + p = line; | |
451 | + while (*p++); | |
452 | + arg = p; | |
453 | + if (!arg || *arg == '\0') | |
454 | + fatal("%s line %d: missing groupname",filename, linenum); | |
455 | + arg[strlen(arg) - 1] = '\0'; | |
456 | + options->myldap_opt.mgroup = xstrdup(arg); | |
457 | + memset(arg,0,strlen(arg)); | |
458 | + break; | |
459 | +#endif | |
460 | ||
461 | default: | |
462 | fatal("%s line %d: Missing handler for opcode %s (%d)", | |
463 | diff -ru openssh-3.6.1p1/servconf.h openssh-3.6.1p1-ldappubkey/servconf.h | |
464 | --- openssh-3.6.1p1/servconf.h Thu Aug 1 03:28:39 2002 | |
465 | +++ openssh-3.6.1p1-ldappubkey/servconf.h Thu Apr 17 11:57:48 2003 | |
466 | @@ -32,6 +32,22 @@ | |
467 | #define PERMIT_NO_PASSWD 2 | |
468 | #define PERMIT_YES 3 | |
469 | ||
470 | +#ifdef WITH_LDAP_PUBKEY | |
471 | +#define _DEFAULT_LDAP_PUBKEY_SERVER "localhost" | |
472 | +#define _DEFAULT_BASEDN "ou=People,dc=company,dc=net" | |
473 | +#define _DEFAULT_BINDDN NULL | |
474 | +#define _DEFAULT_BINDPW NULL | |
475 | +#define _DEFAULT_MGROUP NULL | |
476 | + | |
477 | +typedef struct { | |
478 | + int pubkey_from_ldap; | |
479 | + char *ldap_server; /* ldap URL format where pubkeys are */ | |
480 | + char *binddn; /* ldap base dn where users resides */ | |
481 | + char *bindpw; /* ldap bind passwd */ | |
482 | + char *mgroup; /* ldap server group name, NULL if deactivated */ | |
483 | +} ldap_opt; | |
484 | +#endif | |
485 | + | |
486 | ||
487 | typedef struct { | |
488 | u_int num_ports; | |
489 | @@ -132,6 +148,9 @@ | |
490 | char *authorized_keys_file; /* File containing public keys */ | |
491 | char *authorized_keys_file2; | |
492 | int pam_authentication_via_kbd_int; | |
493 | +#ifdef WITH_LDAP_PUBKEY | |
494 | + ldap_opt myldap_opt; | |
495 | +#endif | |
496 | } ServerOptions; | |
497 | ||
498 | void initialize_server_options(ServerOptions *); | |
499 | diff -ru openssh-3.6.1p1/sshd_config openssh-3.6.1p1-ldappubkey/sshd_config | |
500 | --- openssh-3.6.1p1/sshd_config Fri Sep 27 05:21:58 2002 | |
501 | +++ openssh-3.6.1p1-ldappubkey/sshd_config Thu Apr 17 12:21:43 2003 | |
502 | @@ -89,5 +89,13 @@ | |
503 | #Banner /some/path | |
504 | #VerifyReverseMapping no | |
505 | ||
506 | +# here is the new patched ldap related tokens | |
507 | +# entries in your LDAP must be posixAccount & strongAuthenticationUser | |
508 | +pubkeyfromldap yes | |
509 | +ldapserver ldap://localhost/ou=users,dc=cuckoos,dc=net | |
510 | +binddn cn=Manager,dc=cuckoos,dc=net | |
511 | +bindpw secret | |
512 | +mygroup unixmail | |
513 | + | |
514 | # override default of no subsystems | |
515 | Subsystem sftp /usr/libexec/sftp-server |