1/* 2 Unix SMB/Netbios implementation. 3 Version 1.9. 4 LDAP protocol helper functions for SAMBA 5 Copyright (C) Jean Fran�ois Micouleau 1998 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 21*/ 22/* Must have this here if we want to test WITH_LDAP ... */ 23#include "includes.h" 24 25#ifdef WITH_LDAP 26 27#include <lber.h> 28#include <ldap.h> 29 30#define ADD_USER 1 31#define MODIFY_USER 2 32 33extern int DEBUGLEVEL; 34 35/******************************************************************* 36 open a connection to the ldap serve. 37******************************************************************/ 38static BOOL ldap_open_connection(LDAP **ldap_struct) 39{ 40 if ( (*ldap_struct = ldap_open(lp_ldap_server(),lp_ldap_port()) ) == NULL) 41 { 42 DEBUG( 0, ( "The LDAP server is not responding !\n" ) ); 43 return( False ); 44 } 45 DEBUG(2,("ldap_open_connection: connection opened\n")); 46 return (True); 47} 48 49 50/******************************************************************* 51 connect anonymously to the ldap server. 52 FIXME: later (jfm) 53******************************************************************/ 54static BOOL ldap_connect_anonymous(LDAP *ldap_struct) 55{ 56 if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS) 57 { 58 DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) ); 59 return(False); 60 } 61 return (True); 62} 63 64 65/******************************************************************* 66 connect to the ldap server under system privileg. 67******************************************************************/ 68static BOOL ldap_connect_system(LDAP *ldap_struct) 69{ 70 if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS) 71 { 72 DEBUG( 0, ( "Couldn't bind to the LDAP server!\n" ) ); 73 return(False); 74 } 75 DEBUG(2,("ldap_connect_system: succesful connection to the LDAP server\n")); 76 return (True); 77} 78 79/******************************************************************* 80 connect to the ldap server under a particular user. 81******************************************************************/ 82static BOOL ldap_connect_user(LDAP *ldap_struct, char *user, char *password) 83{ 84 if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS) 85 { 86 DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) ); 87 return(False); 88 } 89 DEBUG(2,("ldap_connect_user: succesful connection to the LDAP server\n")); 90 return (True); 91} 92 93/******************************************************************* 94 run the search by name. 95******************************************************************/ 96static BOOL ldap_search_one_user(LDAP *ldap_struct, char *filter, LDAPMessage **result) 97{ 98 int scope = LDAP_SCOPE_ONELEVEL; 99 int rc; 100 101 DEBUG(2,("ldap_search_one_user: searching for:[%s]\n", filter)); 102 103 rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, result); 104 105 if (rc ! = LDAP_SUCCESS ) 106 { 107 DEBUG( 0, ( "Problem during the LDAP search\n" ) ); 108 return(False); 109 } 110 return (True); 111} 112 113/******************************************************************* 114 run the search by name. 115******************************************************************/ 116static BOOL ldap_search_one_user_by_name(LDAP *ldap_struct, char *user, LDAPMessage **result) 117{ 118 pstring filter; 119 /* 120 in the filter expression, replace %u with the real name 121 so in ldap filter, %u MUST exist :-) 122 */ 123 pstrcpy(filter,lp_ldap_filter()); 124 pstring_sub(filter,"%u",user); 125 126 if ( !ldap_search_one_user(ldap_struct, filter, result) ) 127 { 128 return(False); 129 } 130 return (True); 131} 132 133/******************************************************************* 134 run the search by uid. 135******************************************************************/ 136static BOOL ldap_search_one_user_by_uid(LDAP *ldap_struct, int uid, LDAPMessage **result) 137{ 138 pstring filter; 139 140 slprintf(filter, sizeof(pstring)-1, "uidAccount = %d", uid); 141 142 if ( !ldap_search_one_user(ldap_struct, filter, result) ) 143 { 144 return(False); 145 } 146 return (True); 147} 148 149/******************************************************************* 150 search an attribute and return the first value found. 151******************************************************************/ 152static void get_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char *attribute, char *value) 153{ 154 char **valeurs; 155 156 if ( (valeurs = ldap_get_values(ldap_struct, entry, attribute)) ! = NULL) 157 { 158 pstrcpy(value, valeurs[0]); 159 ldap_value_free(valeurs); 160 DEBUG(3,("get_single_attribute: [%s] = [%s]\n", attribute, value)); 161 } 162 else 163 { 164 value = NULL; 165 } 166} 167 168/******************************************************************* 169 check if the returned entry is a sambaAccount objectclass. 170******************************************************************/ 171static BOOL ldap_check_user(LDAP *ldap_struct, LDAPMessage *entry) 172{ 173 BOOL sambaAccount = False; 174 char **valeur; 175 int i; 176 177 DEBUG(2,("ldap_check_user: ")); 178 valeur = ldap_get_values(ldap_struct, entry, "objectclass"); 179 if (valeur! = NULL) 180 { 181 for (i = 0;valeur[i]! = NULL;i++) 182 { 183 if (!strcmp(valeur[i],"sambaAccount")) sambaAccount = True; 184 } 185 } 186 DEBUG(2,("%s\n",sambaAccount?"yes":"no")); 187 ldap_value_free(valeur); 188 return (sambaAccount); 189} 190 191/******************************************************************* 192 check if the returned entry is a sambaTrust objectclass. 193******************************************************************/ 194static BOOL ldap_check_trust(LDAP *ldap_struct, LDAPMessage *entry) 195{ 196 BOOL sambaTrust = False; 197 char **valeur; 198 int i; 199 200 DEBUG(2,("ldap_check_trust: ")); 201 valeur = ldap_get_values(ldap_struct, entry, "objectclass"); 202 if (valeur! = NULL) 203 { 204 for (i = 0;valeur[i]! = NULL;i++) 205 { 206 if (!strcmp(valeur[i],"sambaTrust")) sambaTrust = True; 207 } 208 } 209 DEBUG(2,("%s\n",sambaTrust?"yes":"no")); 210 ldap_value_free(valeur); 211 return (sambaTrust); 212} 213 214/******************************************************************* 215 retrieve the user's info and contruct a smb_passwd structure. 216******************************************************************/ 217static void ldap_get_smb_passwd(LDAP *ldap_struct,LDAPMessage *entry, 218 struct smb_passwd *user) 219{ 220 static pstring user_name; 221 static pstring user_pass; 222 static pstring temp; 223 static unsigned char smblmpwd[16]; 224 static unsigned char smbntpwd[16]; 225 226 pdb_init_smb(user); 227 228 memset((char *)smblmpwd, '\0', sizeof(smblmpwd)); 229 memset((char *)smbntpwd, '\0', sizeof(smbntpwd)); 230 231 get_single_attribute(ldap_struct, entry, "cn", user_name); 232 DEBUG(2,("ldap_get_smb_passwd: user: %s\n",user_name)); 233 234#ifdef LDAP_PLAINTEXT_PASSWORD 235 get_single_attribute(ldap_struct, entry, "userPassword", temp); 236 nt_lm_owf_gen(temp, user->smb_nt_passwd, user->smb_passwd); 237 memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */ 238#else 239 get_single_attribute(ldap_struct, entry, "unicodePwd", temp); 240 pdb_gethexpwd(temp, smbntpwd); 241 memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */ 242 243 get_single_attribute(ldap_struct, entry, "dBCSPwd", temp); 244 pdb_gethexpwd(temp, smblmpwd); 245 memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */ 246#endif 247 248 get_single_attribute(ldap_struct, entry, "userAccountControl", temp); 249 user->acct_ctrl = pdb_decode_acct_ctrl(temp); 250 251 get_single_attribute(ldap_struct, entry, "pwdLastSet", temp); 252 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 253 254 get_single_attribute(ldap_struct, entry, "rid", temp); 255 256 /* the smb (unix) ids are not stored: they are created */ 257 user->smb_userid = pdb_user_rid_to_uid (atoi(temp)); 258 259 if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) ) 260 { 261 DEBUG(0,("Inconsistency in the LDAP database\n")); 262 } 263 if (user->acct_ctrl & ACB_NORMAL) 264 { 265 user->smb_name = user_name; 266 user->smb_passwd = smblmpwd; 267 user->smb_nt_passwd = smbntpwd; 268 } 269} 270 271/******************************************************************* 272 retrieve the user's info and contruct a sam_passwd structure. 273 274 calls ldap_get_smb_passwd function first, though, to save code duplication. 275 276******************************************************************/ 277static void ldap_get_sam_passwd(LDAP *ldap_struct, LDAPMessage *entry, 278 struct sam_passwd *user) 279{ 280 static pstring user_name; 281 static pstring fullname; 282 static pstring home_dir; 283 static pstring dir_drive; 284 static pstring logon_script; 285 static pstring profile_path; 286 static pstring acct_desc; 287 static pstring workstations; 288 static pstring temp; 289 static struct smb_passwd pw_buf; 290 291 pdb_init_sam(user); 292 293 ldap_get_smb_passwd(ldap_struct, entry, &pw_buf); 294 295 user->pass_last_set_time = pw_buf.pass_last_set_time; 296 297 get_single_attribute(ldap_struct, entry, "logonTime", temp); 298 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 299 300 get_single_attribute(ldap_struct, entry, "logoffTime", temp); 301 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 302 303 get_single_attribute(ldap_struct, entry, "kickoffTime", temp); 304 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 305 306 get_single_attribute(ldap_struct, entry, "pwdLastSet", temp); 307 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 308 309 get_single_attribute(ldap_struct, entry, "pwdCanChange", temp); 310 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 311 312 get_single_attribute(ldap_struct, entry, "pwdMustChange", temp); 313 user->pass_last_set_time = (time_t)strtol(temp, NULL, 16); 314 315 user->smb_name = pw_buf.smb_name; 316 317 DEBUG(2,("ldap_get_sam_passwd: user: %s\n", user_name)); 318 319 get_single_attribute(ldap_struct, entry, "userFullName", fullname); 320 user->full_name = fullname; 321 322 get_single_attribute(ldap_struct, entry, "homeDirectory", home_dir); 323 user->home_dir = home_dir; 324 325 get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive); 326 user->dir_drive = dir_drive; 327 328 get_single_attribute(ldap_struct, entry, "scriptPath", logon_script); 329 user->logon_script = logon_script; 330 331 get_single_attribute(ldap_struct, entry, "profilePath", profile_path); 332 user->profile_path = profile_path; 333 334 get_single_attribute(ldap_struct, entry, "comment", acct_desc); 335 user->acct_desc = acct_desc; 336 337 get_single_attribute(ldap_struct, entry, "userWorkstations", workstations); 338 user->workstations = workstations; 339 340 user->unknown_str = NULL; /* don't know, yet! */ 341 user->munged_dial = NULL; /* "munged" dial-back telephone number */ 342 343 get_single_attribute(ldap_struct, entry, "rid", temp); 344 user->user_rid = atoi(temp); 345 346 get_single_attribute(ldap_struct, entry, "primaryGroupID", temp); 347 user->group_rid = atoi(temp); 348 349 /* the smb (unix) ids are not stored: they are created */ 350 user->smb_userid = pw_buf.smb_userid; 351 user->smb_grpid = group_rid_to_uid(user->group_rid); 352 353 user->acct_ctrl = pw_buf.acct_ctrl; 354 355 user->unknown_3 = 0xffffff; /* don't know */ 356 user->logon_divs = 168; /* hours per week */ 357 user->hours_len = 21; /* 21 times 8 bits = 168 */ 358 memset(user->hours, 0xff, user->hours_len); /* available at all hours */ 359 user->unknown_5 = 0x00020000; /* don't know */ 360 user->unknown_5 = 0x000004ec; /* don't know */ 361 362 if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) ) 363 { 364 DEBUG(0,("Inconsistency in the LDAP database\n")); 365 } 366 367 if (!(user->acct_ctrl & ACB_NORMAL)) 368 { 369 DEBUG(0,("User's acct_ctrl bits not set to ACT_NORMAL in LDAP database\n")); 370 return; 371 } 372} 373 374/************************************************************************ 375 Routine to manage the LDAPMod structure array 376 manage memory used by the array, by each struct, and values 377 378************************************************************************/ 379static void make_a_mod(LDAPMod ***modlist,int modop, char *attribute, char *value) 380{ 381 LDAPMod **mods; 382 int i; 383 int j; 384 385 mods = *modlist; 386 387 if (mods == NULL) 388 { 389 mods = (LDAPMod **)malloc( sizeof(LDAPMod *) ); 390 if (mods == NULL) 391 { 392 DEBUG(0,("make_a_mod: out of memory!\n")); 393 return; 394 } 395 mods[0] = NULL; 396 } 397 398 for ( i = 0; mods[ i ] ! = NULL; ++i ) 399 { 400 if ( mods[ i ]->mod_op == modop && 401 !strcasecmp( mods[ i ]->mod_type, attribute ) ) 402 { 403 break; 404 } 405 } 406 407 if (mods[i] == NULL) 408 { 409 mods = (LDAPMod **)realloc( mods, (i+2) * sizeof( LDAPMod * ) ); 410 if (mods == NULL) 411 { 412 DEBUG(0,("make_a_mod: out of memory!\n")); 413 return; 414 } 415 mods[i] = (LDAPMod *)malloc( sizeof( LDAPMod ) ); 416 if (mods[i] == NULL) 417 { 418 DEBUG(0,("make_a_mod: out of memory!\n")); 419 return; 420 } 421 mods[i]->mod_op = modop; 422 mods[i]->mod_values = NULL; 423 mods[i]->mod_type = strdup( attribute ); 424 mods[i+1] = NULL; 425 } 426 427 if (value ! = NULL ) 428 { 429 j = 0; 430 if ( mods[ i ]->mod_values ! = NULL ) 431 { 432 for ( ; mods[ i ]->mod_values[ j ] ! = NULL; j++ ); 433 } 434 mods[ i ]->mod_values = (char **)realloc(mods[ i ]->mod_values, 435 (j+2) * sizeof( char * )); 436 if ( mods[ i ]->mod_values == NULL) 437 { 438 DEBUG(0, "make_a_mod: Memory allocation failure!\n"); 439 return; 440 } 441 mods[ i ]->mod_values[ j ] = strdup(value); 442 mods[ i ]->mod_values[ j + 1 ] = NULL; 443 } 444 *modlist = mods; 445} 446 447/************************************************************************ 448 Add or modify an entry. Only the smb struct values 449 450*************************************************************************/ 451static BOOL modadd_ldappwd_entry(struct smb_passwd *newpwd, int flag) 452{ 453 454 /* assume the struct is correct and filled 455 that's the job of passdb.c to check */ 456 int scope = LDAP_SCOPE_ONELEVEL; 457 int rc; 458 char *smb_name; 459 int trust = False; 460 int ldap_state; 461 pstring filter; 462 pstring dn; 463 pstring lmhash; 464 pstring nthash; 465 pstring rid; 466 pstring lst; 467 pstring temp; 468 469 LDAP *ldap_struct; 470 LDAPMessage *result; 471 LDAPMod **mods; 472 473 smb_name = newpwd->smb_name; 474 475 if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */ 476 { 477 return False; 478 } 479 480 if (!ldap_connect_system(ldap_struct)) /* connect as system account */ 481 { 482 ldap_unbind(ldap_struct); 483 return False; 484 } 485 486 if (smb_name[strlen(smb_name)-1] == '$' ) 487 { 488 smb_name[strlen(smb_name)-1] = '\0'; 489 trust = True; 490 } 491 492 slprintf(filter, sizeof(filter)-1, 493 "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))", 494 smb_name); 495 496 rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result); 497 498 switch (flag) 499 { 500 case ADD_USER: 501 { 502 if (ldap_count_entries(ldap_struct, result) ! = 0) 503 { 504 DEBUG(0,("User already in the base, with samba properties\n")); 505 ldap_unbind(ldap_struct); 506 return False; 507 } 508 ldap_state = LDAP_MOD_ADD; 509 break; 510 } 511 case MODIFY_USER: 512 { 513 if (ldap_count_entries(ldap_struct, result) ! = 1) 514 { 515 DEBUG(0,("No user to modify !\n")); 516 ldap_unbind(ldap_struct); 517 return False; 518 } 519 ldap_state = LDAP_MOD_REPLACE; 520 break; 521 } 522 default: 523 { 524 DEBUG(0,("How did you come here? \n")); 525 ldap_unbind(ldap_struct); 526 return False; 527 break; 528 } 529 } 530 slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() ); 531 532 if (newpwd->smb_passwd ! = NULL) 533 { 534 int i; 535 for( i = 0; i < 16; i++) 536 { 537 slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_passwd[i]); 538 } 539 540 } 541 else 542 { 543 if (newpwd->acct_ctrl & ACB_PWNOTREQ) 544 { 545 slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); 546 } 547 else 548 { 549 slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 550 } 551 } 552 slprintf(lmhash, sizeof(lmhash)-1, "%s", temp); 553 554 if (newpwd->smb_nt_passwd ! = NULL) 555 { 556 int i; 557 for( i = 0; i < 16; i++) 558 { 559 slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_nt_passwd[i]); 560 } 561 562 } 563 else 564 { 565 if (newpwd->acct_ctrl & ACB_PWNOTREQ) 566 { 567 slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX"); 568 } 569 else 570 { 571 slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); 572 } 573 } 574 slprintf(nthash, sizeof(nthash)-1, "%s", temp); 575 576 slprintf(rid, sizeof(rid)-1, "%d", uid_to_user_rid(newpwd->smb_userid) ); 577 slprintf(lst, sizeof(lst)-1, "%08X", newpwd->pass_last_set_time); 578 579 mods = NULL; 580 581 if (trust) 582 { 583 make_a_mod(&mods, ldap_state, "objectclass", "sambaTrust"); 584 make_a_mod(&mods, ldap_state, "netbiosTrustName", smb_name); 585 make_a_mod(&mods, ldap_state, "trustPassword", nthash); 586 } 587 else 588 { 589 make_a_mod(&mods, ldap_state, "objectclass", "sambaAccount"); 590 make_a_mod(&mods, ldap_state, "dBCSPwd", lmhash); 591 make_a_mod(&mods, ldap_state, "uid", smb_name); 592 make_a_mod(&mods, ldap_state, "unicodePwd", nthash); 593 } 594 595 make_a_mod(&mods, ldap_state, "cn", smb_name); 596 597 make_a_mod(&mods, ldap_state, "rid", rid); 598 make_a_mod(&mods, ldap_state, "pwdLastSet", lst); 599 make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN)); 600 601 switch(flag) 602 { 603 case ADD_USER: 604 { 605 ldap_add_s(ldap_struct, dn, mods); 606 DEBUG(2,("modadd_ldappwd_entry: added: cn = %s in the LDAP database\n",smb_name)); 607 break; 608 } 609 case MODIFY_USER: 610 { 611 ldap_modify_s(ldap_struct, dn, mods); 612 DEBUG(2,("modadd_ldappwd_entry: changed: cn = %s in the LDAP database_n",smb_name)); 613 break; 614 } 615 default: 616 { 617 DEBUG(2,("modadd_ldappwd_entry: How did you come here? \n")); 618 ldap_unbind(ldap_struct); 619 return False; 620 break; 621 } 622 } 623 624 ldap_mods_free(mods, 1); 625 626 ldap_unbind(ldap_struct); 627 628 return True; 629} 630 631/************************************************************************ 632 Add or modify an entry. everything except the smb struct 633 634*************************************************************************/ 635static BOOL modadd_ldap21pwd_entry(struct sam_passwd *newpwd, int flag) 636{ 637 638 /* assume the struct is correct and filled 639 that's the job of passdb.c to check */ 640 int scope = LDAP_SCOPE_ONELEVEL; 641 int rc; 642 char *smb_name; 643 int trust = False; 644 int ldap_state; 645 pstring filter; 646 pstring dn; 647 pstring lmhash; 648 pstring nthash; 649 pstring rid; 650 pstring lst; 651 pstring temp; 652 653 LDAP *ldap_struct; 654 LDAPMessage *result; 655 LDAPMod **mods; 656 657 smb_name = newpwd->smb_name; 658 659 if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */ 660 { 661 return False; 662 } 663 664 if (!ldap_connect_system(ldap_struct)) /* connect as system account */ 665 { 666 ldap_unbind(ldap_struct); 667 return False; 668 } 669 670 if (smb_name[strlen(smb_name)-1] == '$' ) 671 { 672 smb_name[strlen(smb_name)-1] = '\0'; 673 trust = True; 674 } 675 676 slprintf(filter, sizeof(filter)-1, 677 "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))", 678 smb_name); 679 680 rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result); 681 682 switch (flag) 683 { 684 case ADD_USER: 685 { 686 if (ldap_count_entries(ldap_struct, result) ! = 1) 687 { 688 DEBUG(2,("User already in the base, with samba properties\n")); 689 ldap_unbind(ldap_struct); 690 return False; 691 } 692 ldap_state = LDAP_MOD_ADD; 693 break; 694 } 695 696 case MODIFY_USER: 697 { 698 if (ldap_count_entries(ldap_struct, result) ! = 1) 699 { 700 DEBUG(2,("No user to modify !\n")); 701 ldap_unbind(ldap_struct); 702 return False; 703 } 704 ldap_state = LDAP_MOD_REPLACE; 705 break; 706 } 707 708 default: 709 { 710 DEBUG(2,("How did you come here? \n")); 711 ldap_unbind(ldap_struct); 712 return False; 713 break; 714 } 715 } 716 slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() ); 717 718 mods = NULL; 719 720 if (trust) 721 { 722 } 723 else 724 { 725 } 726 727 make_a_mod(&mods, ldap_state, "cn", smb_name); 728 729 make_a_mod(&mods, ldap_state, "rid", rid); 730 make_a_mod(&mods, ldap_state, "pwdLastSet", lst); 731 make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl,NEW_PW_FORMAT_SPACE_PADDED_LEN)); 732 733 ldap_modify_s(ldap_struct, dn, mods); 734 735 ldap_mods_free(mods, 1); 736 737 ldap_unbind(ldap_struct); 738 739 return True; 740} 741 742/************************************************************************ 743 Routine to add an entry to the ldap passwd file. 744 745 do not call this function directly. use passdb.c instead. 746 747*************************************************************************/ 748static BOOL add_ldappwd_entry(struct smb_passwd *newpwd) 749{ 750 return (modadd_ldappwd_entry(newpwd, ADD_USER) ); 751} 752 753/************************************************************************ 754 Routine to search the ldap passwd file for an entry matching the username. 755 and then modify its password entry. We can't use the startldappwent()/ 756 getldappwent()/endldappwent() interfaces here as we depend on looking 757 in the actual file to decide how much room we have to write data. 758 override = False, normal 759 override = True, override XXXXXXXX'd out password or NO PASS 760 761 do not call this function directly. use passdb.c instead. 762 763************************************************************************/ 764static BOOL mod_ldappwd_entry(struct smb_passwd *pwd, BOOL override) 765{ 766 return (modadd_ldappwd_entry(pwd, MODIFY_USER) ); 767} 768 769/************************************************************************ 770 Routine to add an entry to the ldap passwd file. 771 772 do not call this function directly. use passdb.c instead. 773 774*************************************************************************/ 775static BOOL add_ldap21pwd_entry(struct sam_passwd *newpwd) 776{ 777 return( modadd_ldappwd_entry(newpwd, ADD_USER)? 778 modadd_ldap21pwd_entry(newpwd, ADD_USER):False); 779} 780 781/************************************************************************ 782 Routine to search the ldap passwd file for an entry matching the username. 783 and then modify its password entry. We can't use the startldappwent()/ 784 getldappwent()/endldappwent() interfaces here as we depend on looking 785 in the actual file to decide how much room we have to write data. 786 override = False, normal 787 override = True, override XXXXXXXX'd out password or NO PASS 788 789 do not call this function directly. use passdb.c instead. 790 791************************************************************************/ 792static BOOL mod_ldap21pwd_entry(struct sam_passwd *pwd, BOOL override) 793{ 794 return( modadd_ldappwd_entry(pwd, MODIFY_USER)? 795 modadd_ldap21pwd_entry(pwd, MODIFY_USER):False); 796} 797 798struct ldap_enum_info 799{ 800 LDAP *ldap_struct; 801 LDAPMessage *result; 802 LDAPMessage *entry; 803}; 804 805static struct ldap_enum_info ldap_ent; 806 807/*************************************************************** 808 Start to enumerate the ldap passwd list. Returns a void pointer 809 to ensure no modification outside this module. 810 811 do not call this function directly. use passdb.c instead. 812 813 ****************************************************************/ 814static void *startldappwent(BOOL update) 815{ 816 int scope = LDAP_SCOPE_ONELEVEL; 817 int rc; 818 819 pstring filter; 820 821 if (!ldap_open_connection(&ldap_ent.ldap_struct)) /* open a connection to the server */ 822 { 823 return NULL; 824 } 825 826 if (!ldap_connect_system(ldap_ent.ldap_struct)) /* connect as system account */ 827 { 828 return NULL; 829 } 830 831 /* when the class is known the search is much faster */ 832 switch (0) 833 { 834 case 1: 835 { 836 pstrcpy(filter, "objectclass = sambaAccount"); 837 break; 838 } 839 case 2: 840 { 841 pstrcpy(filter, "objectclass = sambaTrust"); 842 break; 843 } 844 default: 845 { 846 pstrcpy(filter, "(|(objectclass = sambaTrust)(objectclass = sambaAccount))"); 847 break; 848 } 849 } 850 851 rc = ldap_search_s(ldap_ent.ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &ldap_ent.result); 852 853 DEBUG(2,("%d entries in the base!\n", ldap_count_entries(ldap_ent.ldap_struct, ldap_ent.result) )); 854 855 ldap_ent.entry = ldap_first_entry(ldap_ent.ldap_struct, ldap_ent.result); 856 857 return &ldap_ent; 858} 859 860/************************************************************************* 861 Routine to return the next entry in the ldap passwd list. 862 863 do not call this function directly. use passdb.c instead. 864 865 *************************************************************************/ 866static struct smb_passwd *getldappwent(void *vp) 867{ 868 static struct smb_passwd user; 869 struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp; 870 871 ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry); 872 873 if (ldap_vp->entry ! = NULL) 874 { 875 ldap_get_smb_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user); 876 return &user; 877 } 878 return NULL; 879} 880 881/************************************************************************* 882 Routine to return the next entry in the ldap passwd list. 883 884 do not call this function directly. use passdb.c instead. 885 886 *************************************************************************/ 887static struct sam_passwd *getldap21pwent(void *vp) 888{ 889 static struct sam_passwd user; 890 struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp; 891 892 ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry); 893 894 if (ldap_vp->entry ! = NULL) 895 { 896 ldap_get_sam_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user); 897 return &user; 898 } 899 return NULL; 900} 901 902/*************************************************************** 903 End enumeration of the ldap passwd list. 904 905 do not call this function directly. use passdb.c instead. 906 907****************************************************************/ 908static void endldappwent(void *vp) 909{ 910 struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp; 911 ldap_msgfree(ldap_vp->result); 912 ldap_unbind(ldap_vp->ldap_struct); 913} 914 915/************************************************************************* 916 Return the current position in the ldap passwd list as an SMB_BIG_UINT. 917 This must be treated as an opaque token. 918 919 do not call this function directly. use passdb.c instead. 920 921*************************************************************************/ 922static SMB_BIG_UINT getldappwpos(void *vp) 923{ 924 return (SMB_BIG_UINT)0; 925} 926 927/************************************************************************* 928 Set the current position in the ldap passwd list from SMB_BIG_UINT. 929 This must be treated as an opaque token. 930 931 do not call this function directly. use passdb.c instead. 932 933*************************************************************************/ 934static BOOL setldappwpos(void *vp, SMB_BIG_UINT tok) 935{ 936 return False; 937} 938 939/* 940 * Ldap derived functions. 941 */ 942 943static struct smb_passwd *getldappwnam(char *name) 944{ 945 return pdb_sam_to_smb(iterate_getsam21pwnam(name)); 946} 947 948static struct smb_passwd *getldappwuid(uid_t smb_userid) 949{ 950 return pdb_sam_to_smb(iterate_getsam21pwuid(smb_userid)); 951} 952 953static struct smb_passwd *getldappwrid(uint32 user_rid) 954{ 955 return pdb_sam_to_smb(iterate_getsam21pwuid(pdb_user_rid_to_uid(user_rid))); 956} 957 958static struct smb_passwd *getldappwent(void *vp) 959{ 960 return pdb_sam_to_smb(getldap21pwent(vp)); 961} 962 963static BOOL add_ldappwd_entry(struct smb_passwd *newpwd) 964{ 965 return add_ldap21pwd_entry(pdb_smb_to_sam(newpwd)); 966} 967 968static BOOL mod_ldappwd_entry(struct smb_passwd* pwd, BOOL override) 969{ 970 return mod_ldap21pwd_entry(pdb_smb_to_sam(pwd), override); 971} 972 973static BOOL del_ldappwd_entry(const char *name) 974{ 975 return False; /* Dummy... */ 976} 977 978static struct sam_disp_info *getldapdispnam(char *name) 979{ 980 return pdb_sam_to_dispinfo(getldap21pwnam(name)); 981} 982 983static struct sam_disp_info *getldapdisprid(uint32 rid) 984{ 985 return pdb_sam_to_dispinfo(getldap21pwrid(rid)); 986} 987 988static struct sam_disp_info *getldapdispent(void *vp) 989{ 990 return pdb_sam_to_dispinfo(getldap21pwent(vp)); 991} 992 993static struct sam_passwd *getldap21pwuid(uid_t uid) 994{ 995 return pdb_smb_to_sam(iterate_getsam21pwuid(pdb_uid_to_user_rid(uid))); 996} 997 998static struct passdb_ops ldap_ops = 999{ 1000 startldappwent, 1001 endldappwent, 1002 getldappwpos, 1003 setldappwpos, 1004 getldappwnam, 1005 getldappwuid, 1006 getldappwrid, 1007 getldappwent, 1008 add_ldappwd_entry, 1009 mod_ldappwd_entry, 1010 del_ldappwd_entry, 1011 getldap21pwent, 1012 iterate_getsam21pwnam, /* From passdb.c */ 1013 iterate_getsam21pwuid, /* From passdb.c */ 1014 iterate_getsam21pwrid, /* From passdb.c */ 1015 add_ldap21pwd_entry, 1016 mod_ldap21pwd_entry, 1017 getldapdispnam, 1018 getldapdisprid, 1019 getldapdispent 1020}; 1021 1022struct passdb_ops *ldap_initialize_password_db(void) 1023{ 1024 return &ldap_ops; 1025} 1026 1027#else 1028 void dummy_function(void); 1029 void dummy_function(void) { } /* stop some compilers complaining */ 1030#endif 1031