1 2/* 3 * Unix SMB/CIFS implementation. 4 * MS-RPC client internal functions 5 * Copyright (C) Chris Nicholls 2005. 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 23#include "libmsrpc.h" 24#include "libmsrpc_internal.h" 25 26char *cac_unistr_to_str( TALLOC_CTX * mem_ctx, uint16 * src, int num_bytes ); 27char *talloc_unistr2_to_ascii( TALLOC_CTX * mem_ctx, UNISTR2 str ); 28char *cac_unistr_ascii( TALLOC_CTX * mem_ctx, UNISTR src ); 29 30/*used to get a struct rpc_pipe_client* to be passed into rpccli* calls*/ 31struct rpc_pipe_client *cac_GetPipe( CacServerHandle * hnd, int pi_idx ) 32{ 33 SMBCSRV *srv = NULL; 34 struct rpc_pipe_client *pipe_hnd = NULL; 35 36 if ( !hnd ) { 37 return NULL; 38 } 39 40 if ( hnd->_internal.pipes[pi_idx] == False ) { 41 hnd->status = NT_STATUS_INVALID_HANDLE; 42 return NULL; 43 } 44 45 srv = cac_GetServer( hnd ); 46 if ( !srv ) { 47 hnd->status = NT_STATUS_INVALID_CONNECTION; 48 return NULL; 49 } 50 51 pipe_hnd = srv->cli->pipe_list; 52 53 while ( pipe_hnd != NULL && pipe_hnd->pipe_idx != pi_idx ) { 54 pipe_hnd = pipe_hnd->next; 55 } 56 57 return pipe_hnd; 58} 59 60/*takes a string like HKEY_LOCAL_MACHINE\HARDWARE\ACPI and returns the reg_type code and then a pointer to the start of the path (HARDWARE)*/ 61int cac_ParseRegPath( char *path, uint32 * reg_type, char **key_name ) 62{ 63 64 if ( !path ) 65 return CAC_FAILURE; 66 67 if ( strncmp( path, "HKLM", 4 ) == 0 ) { 68 *reg_type = HKEY_LOCAL_MACHINE; 69 *key_name = ( path[4] == '\\' ) ? path + 5 : NULL; 70 } else if ( strncmp( path, "HKEY_LOCAL_MACHINE", 18 ) == 0 ) { 71 *reg_type = HKEY_LOCAL_MACHINE; 72 *key_name = ( path[18] == '\\' ) ? path + 19 : NULL; 73 } else if ( strncmp( path, "HKCR", 4 ) == 0 ) { 74 *reg_type = HKEY_CLASSES_ROOT; 75 *key_name = ( path[4] == '\\' ) ? path + 5 : NULL; 76 } else if ( strncmp( path, "HKEY_CLASSES_ROOT", 17 ) == 0 ) { 77 *reg_type = HKEY_CLASSES_ROOT; 78 *key_name = ( path[17] == '\\' ) ? path + 18 : NULL; 79 } else if ( strncmp( path, "HKU", 3 ) == 0 ) { 80 *reg_type = HKEY_USERS; 81 *key_name = ( path[3] == '\\' ) ? path + 4 : NULL; 82 } else if ( strncmp( path, "HKEY_USERS", 10 ) == 0 ) { 83 *reg_type = HKEY_USERS; 84 *key_name = ( path[10] == '\\' ) ? path + 11 : NULL; 85 } else if ( strncmp( path, "HKPD", 4 ) == 0 ) { 86 *reg_type = HKEY_PERFORMANCE_DATA; 87 *key_name = ( path[4] == '\\' ) ? path + 5 : NULL; 88 } else if ( strncmp( path, "HKEY_PERFORMANCE_DATA", 21 ) == 0 ) { 89 *reg_type = HKEY_PERFORMANCE_DATA; 90 *key_name = ( path[21] == '\\' ) ? path + 22 : NULL; 91 } else { 92 return CAC_FAILURE; 93 } 94 95 return CAC_SUCCESS; 96} 97 98 99 100RPC_DATA_BLOB *cac_MakeRpcDataBlob( TALLOC_CTX * mem_ctx, uint32 data_type, 101 REG_VALUE_DATA data ) 102{ 103 RPC_DATA_BLOB *blob = NULL; 104 int i; 105 uint32 size = 0; 106 uint8 *multi = NULL; 107 uint32 multi_idx = 0; 108 109 blob = talloc( mem_ctx, RPC_DATA_BLOB ); 110 111 if ( !blob ) { 112 errno = ENOMEM; 113 return NULL; 114 } 115 116 switch ( data_type ) { 117 case REG_SZ: 118 init_rpc_blob_str( blob, data.reg_sz, 119 strlen( data.reg_sz ) + 1 ); 120 break; 121 122 case REG_EXPAND_SZ: 123 init_rpc_blob_str( blob, data.reg_expand_sz, 124 strlen( data.reg_sz ) + 1 ); 125 break; 126 127 case REG_BINARY: 128 init_rpc_blob_bytes( blob, data.reg_binary.data, 129 data.reg_binary.data_length ); 130 break; 131 132 case REG_DWORD: 133 init_rpc_blob_uint32( blob, data.reg_dword ); 134 break; 135 136 case REG_DWORD_BE: 137 init_rpc_blob_uint32( blob, data.reg_dword_be ); 138 break; 139 140 case REG_MULTI_SZ: 141 /*need to find the size */ 142 for ( i = 0; i < data.reg_multi_sz.num_strings; i++ ) { 143 size += strlen( data.reg_multi_sz.strings[i] ) + 1; 144 } 145 146 /**need a whole bunch of unicode strings in a row (seperated by null characters), with an extra null-character on the end*/ 147 148 multi = TALLOC_ZERO_ARRAY( mem_ctx, uint8, ( size + 1 ) * 2 ); /*size +1 for the extra null character */ 149 if ( !multi ) { 150 errno = ENOMEM; 151 break; 152 } 153 154 /*do it using rpcstr_push() */ 155 multi_idx = 0; 156 for ( i = 0; i < data.reg_multi_sz.num_strings; i++ ) { 157 size_t len = 158 strlen( data.reg_multi_sz.strings[i] ) + 1; 159 160 rpcstr_push( ( multi + multi_idx ), 161 data.reg_multi_sz.strings[i], len * 2, 162 STR_TERMINATE ); 163 164 /* x2 becuase it is a uint8 buffer */ 165 multi_idx += len * 2; 166 } 167 168 /*now initialize the buffer as binary data */ 169 init_rpc_blob_bytes( blob, multi, ( size + 1 ) * 2 ); 170 171 break; 172 173 default: 174 TALLOC_FREE( blob ); 175 blob = NULL; 176 return NULL; 177 } 178 179 if ( !( blob->buffer ) ) { 180 TALLOC_FREE( blob ); 181 return NULL; 182 } 183 184 return blob; 185} 186 187/*turns a string in a uint16 array to a char array*/ 188char *cac_unistr_to_str( TALLOC_CTX * mem_ctx, uint16 * src, int num_bytes ) 189{ 190 char *buf; 191 192 int i = 0; 193 194 uint32 str_len = 0; 195 196 /*don't allocate more space than we need */ 197 while ( ( str_len ) < num_bytes / 2 && src[str_len] != 0x0000 ) 198 str_len++; 199 200 /*need room for a '\0' */ 201 str_len++; 202 203 buf = TALLOC_ARRAY( mem_ctx, char, str_len ); 204 205 if ( !buf ) { 206 return NULL; 207 } 208 209 for ( i = 0; i < num_bytes / 2; i++ ) { 210 buf[i] = ( ( char * ) src )[2 * i]; 211 } 212 213 buf[str_len - 1] = '\0'; 214 215 return buf; 216} 217 218REG_VALUE_DATA *cac_MakeRegValueData( TALLOC_CTX * mem_ctx, uint32 data_type, 219 REGVAL_BUFFER buf ) 220{ 221 REG_VALUE_DATA *data; 222 223 uint32 i; 224 225 /*all of the following used for MULTI_SZ data */ 226 uint32 size = 0; 227 uint32 len = 0; 228 uint32 multi_idx = 0; 229 uint32 num_strings = 0; 230 char **strings = NULL; 231 232 data = talloc( mem_ctx, REG_VALUE_DATA ); 233 if ( !data ) { 234 errno = ENOMEM; 235 return NULL; 236 } 237 238 switch ( data_type ) { 239 case REG_SZ: 240 data->reg_sz = 241 cac_unistr_to_str( mem_ctx, buf.buffer, buf.buf_len ); 242 if ( !data->reg_sz ) { 243 TALLOC_FREE( data ); 244 errno = ENOMEM; 245 data = NULL; 246 } 247 248 break; 249 250 case REG_EXPAND_SZ: 251 data->reg_expand_sz = 252 cac_unistr_to_str( mem_ctx, buf.buffer, buf.buf_len ); 253 254 if ( !data->reg_expand_sz ) { 255 TALLOC_FREE( data ); 256 errno = ENOMEM; 257 data = NULL; 258 } 259 260 break; 261 262 case REG_BINARY: 263 size = buf.buf_len; 264 265 data->reg_binary.data_length = size; 266 267 if (size) { 268 data->reg_binary.data = 269 ( uint8 * ) TALLOC_MEMDUP( mem_ctx, buf.buffer, size ); 270 if ( !data->reg_binary.data ) { 271 TALLOC_FREE( data ); 272 errno = ENOMEM; 273 data = NULL; 274 } 275 } else { 276 data->reg_binary.data = NULL; 277 } 278 break; 279 280 case REG_DWORD: 281 data->reg_dword = *( ( uint32 * ) buf.buffer ); 282 break; 283 284 case REG_DWORD_BE: 285 data->reg_dword_be = *( ( uint32 * ) buf.buffer ); 286 break; 287 288 case REG_MULTI_SZ: 289 size = buf.buf_len; 290 291 /*find out how many strings there are. size is # of bytes and we want to work uint16 */ 292 for ( i = 0; i < ( size / 2 - 1 ); i++ ) { 293 if ( buf.buffer[i] == 0x0000 ) 294 num_strings++; 295 296 /*buffer is suppsed to be terminated with \0\0, but it might not be */ 297 if ( buf.buffer[i] == 0x0000 298 && buf.buffer[i + 1] == 0x0000 ) 299 break; 300 } 301 302 if (num_strings) { 303 strings = TALLOC_ARRAY( mem_ctx, char *, num_strings ); 304 305 if ( !strings ) { 306 errno = ENOMEM; 307 TALLOC_FREE( data ); 308 break; 309 } 310 } else { 311 strings = NULL; 312 } 313 314 if ( num_strings == 0 ) /*then our work here is done */ 315 break; 316 317 for ( i = 0; i < num_strings; i++ ) { 318 /*find out how many characters are in this string */ 319 len = 0; 320 /*make sure we don't go past the end of the buffer and keep looping until we have a uni \0 */ 321 while ( multi_idx + len < size / 2 322 && buf.buffer[multi_idx + len] != 0x0000 ) 323 len++; 324 325 /*stay aware of the \0\0 */ 326 len++; 327 328 strings[i] = TALLOC_ZERO_ARRAY( mem_ctx, char, len ); 329 330 /*pull out the unicode string */ 331 rpcstr_pull( strings[i], ( buf.buffer + multi_idx ), 332 len, -1, STR_TERMINATE ); 333 334 /*keep track of where we are in the bigger array */ 335 multi_idx += len; 336 } 337 338 data->reg_multi_sz.num_strings = num_strings; 339 data->reg_multi_sz.strings = strings; 340 341 break; 342 343 default: 344 TALLOC_FREE( data ); 345 data = NULL; 346 } 347 348 return data; 349} 350 351SAM_USERINFO_CTR *cac_MakeUserInfoCtr( TALLOC_CTX * mem_ctx, 352 CacUserInfo * info ) 353{ 354 SAM_USERINFO_CTR *ctr = NULL; 355 356 /*the flags we are 'setting'- include/passdb.h */ 357 uint32 flags = 358 ACCT_USERNAME | ACCT_FULL_NAME | ACCT_PRIMARY_GID | 359 ACCT_DESCRIPTION | ACCT_COMMENT | ACCT_HOME_DIR | 360 ACCT_HOME_DRIVE | ACCT_LOGON_SCRIPT | ACCT_PROFILE | 361 ACCT_WORKSTATIONS | ACCT_FLAGS; 362 363 NTTIME logon_time; 364 NTTIME logoff_time; 365 NTTIME kickoff_time; 366 NTTIME pass_last_set_time; 367 NTTIME pass_can_change_time; 368 NTTIME pass_must_change_time; 369 370 UNISTR2 user_name; 371 UNISTR2 full_name; 372 UNISTR2 home_dir; 373 UNISTR2 dir_drive; 374 UNISTR2 log_scr; 375 UNISTR2 prof_path; 376 UNISTR2 desc; 377 UNISTR2 wkstas; 378 UNISTR2 mung_dial; 379 UNISTR2 unk; 380 381 ctr = talloc( mem_ctx, SAM_USERINFO_CTR ); 382 if ( !ctr ) 383 return NULL; 384 385 ZERO_STRUCTP( ctr->info.id23 ); 386 387 ctr->info.id21 = talloc( mem_ctx, SAM_USER_INFO_21 ); 388 if ( !ctr->info.id21 ) 389 return NULL; 390 391 ctr->switch_value = 21; 392 393 ZERO_STRUCTP( ctr->info.id21 ); 394 395 unix_to_nt_time( &logon_time, info->logon_time ); 396 unix_to_nt_time( &logoff_time, info->logoff_time ); 397 unix_to_nt_time( &kickoff_time, info->kickoff_time ); 398 unix_to_nt_time( &pass_last_set_time, info->pass_last_set_time ); 399 unix_to_nt_time( &pass_can_change_time, info->pass_can_change_time ); 400 unix_to_nt_time( &pass_must_change_time, 401 info->pass_must_change_time ); 402 403 /*initialize the strings */ 404 init_unistr2( &user_name, info->username, UNI_STR_TERMINATE ); 405 init_unistr2( &full_name, info->full_name, UNI_STR_TERMINATE ); 406 init_unistr2( &home_dir, info->home_dir, UNI_STR_TERMINATE ); 407 init_unistr2( &dir_drive, info->home_drive, UNI_STR_TERMINATE ); 408 init_unistr2( &log_scr, info->logon_script, UNI_STR_TERMINATE ); 409 init_unistr2( &prof_path, info->profile_path, UNI_STR_TERMINATE ); 410 init_unistr2( &desc, info->description, UNI_STR_TERMINATE ); 411 init_unistr2( &wkstas, info->workstations, UNI_STR_TERMINATE ); 412 init_unistr2( &unk, "\0", UNI_STR_TERMINATE ); 413 init_unistr2( &mung_dial, info->dial, UNI_STR_TERMINATE ); 414 415 /*manually set passmustchange */ 416 ctr->info.id21->passmustchange = 417 ( info->pass_must_change ) ? 0x01 : 0x00; 418 419 init_sam_user_info21W( ctr->info.id21, &logon_time, &logoff_time, &kickoff_time, &pass_last_set_time, &pass_can_change_time, &pass_must_change_time, &user_name, &full_name, &home_dir, &dir_drive, &log_scr, &prof_path, &desc, &wkstas, &unk, &mung_dial, info->lm_password, info->nt_password, info->rid, info->group_rid, info->acb_mask, flags, 168, /*logon divs */ 420 info->logon_hours, 421 info->bad_passwd_count, info->logon_count ); 422 423 return ctr; 424 425} 426 427char *talloc_unistr2_to_ascii( TALLOC_CTX * mem_ctx, UNISTR2 str ) 428{ 429 char *buf = NULL; 430 431 if ( !mem_ctx ) 432 return NULL; 433 434 buf = TALLOC_ARRAY( mem_ctx, char, ( str.uni_str_len + 1 ) ); 435 if ( !buf ) 436 return NULL; 437 438 unistr2_to_ascii( buf, &str, str.uni_str_len + 1 ); 439 440 return buf; 441} 442 443CacUserInfo *cac_MakeUserInfo( TALLOC_CTX * mem_ctx, SAM_USERINFO_CTR * ctr ) 444{ 445 CacUserInfo *info = NULL; 446 SAM_USER_INFO_21 *id21 = NULL; 447 448 if ( !ctr || ctr->switch_value != 21 ) 449 return NULL; 450 451 info = talloc( mem_ctx, CacUserInfo ); 452 if ( !info ) 453 return NULL; 454 455 id21 = ctr->info.id21; 456 457 ZERO_STRUCTP( info ); 458 459 info->logon_time = nt_time_to_unix( id21->logon_time ); 460 info->logoff_time = nt_time_to_unix( id21->logoff_time ); 461 info->kickoff_time = nt_time_to_unix( id21->kickoff_time ); 462 info->pass_last_set_time = 463 nt_time_to_unix( id21->pass_last_set_time ); 464 info->pass_can_change_time = 465 nt_time_to_unix( id21->pass_can_change_time ); 466 info->pass_must_change_time = 467 nt_time_to_unix( id21->pass_must_change_time ); 468 469 info->username = 470 talloc_unistr2_to_ascii( mem_ctx, id21->uni_user_name ); 471 if ( !info->username ) 472 return NULL; 473 474 info->full_name = 475 talloc_unistr2_to_ascii( mem_ctx, id21->uni_full_name ); 476 if ( !info->full_name ) 477 return NULL; 478 479 info->home_dir = 480 talloc_unistr2_to_ascii( mem_ctx, id21->uni_home_dir ); 481 if ( !info->home_dir ) 482 return NULL; 483 484 info->home_drive = 485 talloc_unistr2_to_ascii( mem_ctx, id21->uni_dir_drive ); 486 if ( !info->home_drive ) 487 return NULL; 488 489 info->logon_script = 490 talloc_unistr2_to_ascii( mem_ctx, id21->uni_logon_script ); 491 if ( !info->logon_script ) 492 return NULL; 493 494 info->profile_path = 495 talloc_unistr2_to_ascii( mem_ctx, id21->uni_profile_path ); 496 if ( !info->profile_path ) 497 return NULL; 498 499 info->description = 500 talloc_unistr2_to_ascii( mem_ctx, id21->uni_acct_desc ); 501 if ( !info->description ) 502 return NULL; 503 504 info->workstations = 505 talloc_unistr2_to_ascii( mem_ctx, id21->uni_workstations ); 506 if ( !info->workstations ) 507 return NULL; 508 509 info->dial = 510 talloc_unistr2_to_ascii( mem_ctx, id21->uni_munged_dial ); 511 if ( !info->dial ) 512 return NULL; 513 514 info->rid = id21->user_rid; 515 info->group_rid = id21->group_rid; 516 info->acb_mask = id21->acb_info; 517 info->bad_passwd_count = id21->bad_password_count; 518 info->logon_count = id21->logon_count; 519 520 memcpy( info->nt_password, id21->nt_pwd, 8 ); 521 memcpy( info->lm_password, id21->lm_pwd, 8 ); 522 523 info->logon_hours = 524 ( LOGON_HRS * ) TALLOC_MEMDUP( mem_ctx, &( id21->logon_hrs ), 525 sizeof( LOGON_HRS ) ); 526 if ( !info->logon_hours ) 527 return NULL; 528 529 info->pass_must_change = ( id21->passmustchange ) ? True : False; 530 531 return info; 532} 533 534CacGroupInfo *cac_MakeGroupInfo( TALLOC_CTX * mem_ctx, GROUP_INFO_CTR * ctr ) 535{ 536 CacGroupInfo *info = NULL; 537 538 if ( !mem_ctx || !ctr || ctr->switch_value1 != 1 ) 539 return NULL; 540 541 info = talloc( mem_ctx, CacGroupInfo ); 542 if ( !info ) 543 return NULL; 544 545 info->name = 546 talloc_unistr2_to_ascii( mem_ctx, 547 ctr->group.info1.uni_acct_name ); 548 if ( !info->name ) 549 return NULL; 550 551 info->description = 552 talloc_unistr2_to_ascii( mem_ctx, 553 ctr->group.info1.uni_acct_desc ); 554 if ( !info->description ) 555 return NULL; 556 557 info->num_members = ctr->group.info1.num_members; 558 559 return info; 560} 561 562GROUP_INFO_CTR *cac_MakeGroupInfoCtr( TALLOC_CTX * mem_ctx, 563 CacGroupInfo * info ) 564{ 565 GROUP_INFO_CTR *ctr = NULL; 566 567 if ( !mem_ctx || !info ) 568 return NULL; 569 570 ctr = talloc( mem_ctx, GROUP_INFO_CTR ); 571 if ( !ctr ) 572 return NULL; 573 574 ctr->switch_value1 = 1; 575 576 init_samr_group_info1( &( ctr->group.info1 ), info->name, 577 info->description, info->num_members ); 578 579 return ctr; 580} 581 582CacAliasInfo *cac_MakeAliasInfo( TALLOC_CTX * mem_ctx, ALIAS_INFO_CTR ctr ) 583{ 584 CacGroupInfo *info = NULL; 585 586 if ( !mem_ctx || ctr.level != 1 ) 587 return NULL; 588 589 info = talloc( mem_ctx, CacAliasInfo ); 590 if ( !info ) 591 return NULL; 592 593 info->name = 594 talloc_unistr2_to_ascii( mem_ctx, 595 *( ctr.alias.info1.name.string ) ); 596 if ( !info->name ) 597 return NULL; 598 599 info->description = 600 talloc_unistr2_to_ascii( mem_ctx, 601 *( ctr.alias.info1.description. 602 string ) ); 603 if ( !info->name ) 604 return NULL; 605 606 info->num_members = ctr.alias.info1.num_member; 607 608 return info; 609} 610 611ALIAS_INFO_CTR *cac_MakeAliasInfoCtr( TALLOC_CTX * mem_ctx, 612 CacAliasInfo * info ) 613{ 614 ALIAS_INFO_CTR *ctr = NULL; 615 616 if ( !mem_ctx || !info ) 617 return NULL; 618 619 ctr = talloc( mem_ctx, ALIAS_INFO_CTR ); 620 if ( !ctr ) 621 return NULL; 622 623 ctr->level = 1; 624 625 init_samr_alias_info1( &( ctr->alias.info1 ), info->name, 626 info->num_members, info->description ); 627 628 return ctr; 629} 630 631CacDomainInfo *cac_MakeDomainInfo( TALLOC_CTX * mem_ctx, 632 SAM_UNK_INFO_1 * info1, 633 SAM_UNK_INFO_2 * info2, 634 SAM_UNK_INFO_12 * info12 ) 635{ 636 CacDomainInfo *info = NULL; 637 638 if ( !mem_ctx || !info1 || !info2 || !info12 ) 639 return NULL; 640 641 info = talloc( mem_ctx, CacDomainInfo ); 642 if ( !info ) 643 return NULL; 644 645 info->min_pass_length = info1->min_length_password; 646 info->pass_history = info1->password_history; 647 648 cac_InitCacTime( &( info->expire ), info1->expire ); 649 cac_InitCacTime( &( info->min_pass_age ), info1->min_passwordage ); 650 651 info->server_role = info2->server_role; 652 info->num_users = info2->num_domain_usrs; 653 info->num_domain_groups = info2->num_domain_grps; 654 info->num_local_groups = info2->num_local_grps; 655 656 /*if these have been ZERO'd out we need to know. uni_str_len will be 0 */ 657 if ( info2->uni_comment.uni_str_len == 0 ) { 658 info->comment = talloc_strdup( mem_ctx, "\0" ); 659 } else { 660 info->comment = 661 talloc_unistr2_to_ascii( mem_ctx, 662 info2->uni_comment ); 663 } 664 665 if ( info2->uni_domain.uni_str_len == 0 ) { 666 info->domain_name = talloc_strdup( mem_ctx, "\0" ); 667 } else { 668 info->domain_name = 669 talloc_unistr2_to_ascii( mem_ctx, info2->uni_domain ); 670 } 671 672 if ( info2->uni_server.uni_str_len == 0 ) { 673 info->server_name = talloc_strdup( mem_ctx, "\0" ); 674 } else { 675 info->server_name = 676 talloc_unistr2_to_ascii( mem_ctx, info2->uni_server ); 677 } 678 679 680 cac_InitCacTime( &( info->lockout_duration ), info12->duration ); 681 cac_InitCacTime( &( info->lockout_reset ), info12->reset_count ); 682 info->num_bad_attempts = info12->bad_attempt_lockout; 683 684 return info; 685} 686 687char *cac_unistr_ascii( TALLOC_CTX * mem_ctx, UNISTR src ) 688{ 689 char *buf; 690 uint32 len; 691 692 if ( !mem_ctx || !src.buffer ) 693 return NULL; 694 695 len = unistrlen( src.buffer ) + 1; 696 697 buf = TALLOC_ZERO_ARRAY( mem_ctx, char, len ); 698 if ( !buf ) 699 return NULL; 700 701 rpcstr_pull( buf, src.buffer, len, -1, STR_TERMINATE ); 702 703 return buf; 704} 705 706CacService *cac_MakeServiceArray( TALLOC_CTX * mem_ctx, 707 ENUM_SERVICES_STATUS * svc, 708 uint32 num_services ) 709{ 710 int i; 711 CacService *services = NULL; 712 713 if ( !mem_ctx || !svc ) 714 return NULL; 715 716 if (num_services) { 717 services = TALLOC_ZERO_ARRAY( mem_ctx, CacService, num_services ); 718 if ( !services ) 719 return NULL; 720 } else { 721 services = NULL; 722 } 723 724 for ( i = 0; i < num_services; i++ ) { 725 services[i].service_name = 726 cac_unistr_ascii( mem_ctx, svc[i].servicename ); 727 services[i].display_name = 728 cac_unistr_ascii( mem_ctx, svc[i].displayname ); 729 730 if ( !services[i].service_name || !services[i].display_name ) 731 return NULL; 732 733 services[i].status = svc[i].status; 734 } 735 736 return services; 737} 738 739int cac_InitCacServiceConfig( TALLOC_CTX * mem_ctx, SERVICE_CONFIG * src, 740 CacServiceConfig * dest ) 741{ 742 if ( !src || !dest ) 743 return CAC_FAILURE; 744 745 dest->exe_path = 746 talloc_unistr2_to_ascii( mem_ctx, *src->executablepath ); 747 if ( !dest->exe_path ) 748 return CAC_FAILURE; 749 750 dest->load_order_group = 751 talloc_unistr2_to_ascii( mem_ctx, *src->loadordergroup ); 752 if ( !dest->load_order_group ) 753 return CAC_FAILURE; 754 755 dest->dependencies = 756 talloc_unistr2_to_ascii( mem_ctx, *src->dependencies ); 757 if ( !dest->dependencies ) 758 return CAC_FAILURE; 759 760 dest->start_name = 761 talloc_unistr2_to_ascii( mem_ctx, *src->startname ); 762 if ( !dest->start_name ) 763 return CAC_FAILURE; 764 765 dest->display_name = 766 talloc_unistr2_to_ascii( mem_ctx, *src->displayname ); 767 if ( !dest->display_name ) 768 return CAC_FAILURE; 769 770 dest->type = src->service_type; 771 dest->start_type = src->start_type; 772 dest->error_control = src->error_control; 773 dest->tag_id = src->tag_id; 774 775 return CAC_SUCCESS; 776} 777