libmsrpc_internal.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 712 行 · 第 1/2 页
C
712 行
/* * Unix SMB/CIFS implementation. * MS-RPC client internal functions * Copyright (C) Chris Nicholls 2005. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "libmsrpc.h"#include "libmsrpc_internal.h"/*used to get a struct rpc_pipe_client* to be passed into rpccli* calls*/struct rpc_pipe_client *cac_GetPipe(CacServerHandle *hnd, int pi_idx) { SMBCSRV *srv = NULL; struct rpc_pipe_client *pipe_hnd = NULL; if(!hnd) return NULL; if(hnd->_internal.pipes[pi_idx] == False) { hnd->status = NT_STATUS_INVALID_HANDLE; return NULL; } srv = cac_GetServer(hnd); if(!srv) { hnd->status = NT_STATUS_INVALID_CONNECTION; return NULL; } pipe_hnd = srv->cli.pipe_list; while(pipe_hnd != NULL && pipe_hnd->pipe_idx != pi_idx) pipe_hnd = pipe_hnd->next; return pipe_hnd;}/*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)*/int cac_ParseRegPath(char *path, uint32 *reg_type, char **key_name) { if(!path) return CAC_FAILURE; if(strncmp(path, "HKLM", 4) == 0) { *reg_type = HKEY_LOCAL_MACHINE; *key_name = (path[4] == '\\') ? path + 5 : NULL; } else if(strncmp(path, "HKEY_LOCAL_MACHINE", 18) == 0) { *reg_type = HKEY_LOCAL_MACHINE; *key_name = (path[18] == '\\') ? path + 19 : NULL; } else if(strncmp(path, "HKCR", 4) == 0) { *reg_type = HKEY_CLASSES_ROOT; *key_name = (path[4] == '\\') ? path + 5 : NULL; } else if(strncmp(path, "HKEY_CLASSES_ROOT", 17) == 0) { *reg_type = HKEY_CLASSES_ROOT; *key_name = (path[17] == '\\') ? path + 18 : NULL; } else if(strncmp(path, "HKU", 3) == 0) { *reg_type = HKEY_USERS; *key_name = (path[3] == '\\') ? path + 4 : NULL; } else if(strncmp(path, "HKEY_USERS", 10) == 0) { *reg_type = HKEY_USERS; *key_name = (path[10] == '\\') ? path + 11 : NULL; } else if(strncmp(path, "HKPD", 4) == 0) { *reg_type = HKEY_PERFORMANCE_DATA; *key_name = (path[4] == '\\') ? path + 5 : NULL; } else if(strncmp(path, "HKEY_PERFORMANCE_DATA", 21) == 0) { *reg_type = HKEY_PERFORMANCE_DATA; *key_name = (path[21] == '\\') ? path + 22 : NULL; } else { return CAC_FAILURE; } return CAC_SUCCESS;}RPC_DATA_BLOB *cac_MakeRpcDataBlob(TALLOC_CTX *mem_ctx, uint32 data_type, REG_VALUE_DATA data) { RPC_DATA_BLOB *blob = NULL; int i; uint32 size = 0; uint32 len = 0; uint8 *multi = NULL; uint32 multi_idx = 0; blob = talloc(mem_ctx, RPC_DATA_BLOB); if(!blob) { errno = ENOMEM; return NULL; } switch(data_type) { case REG_SZ: init_rpc_blob_str(blob, data.reg_sz, strlen(data.reg_sz ) + 1); break; case REG_EXPAND_SZ: init_rpc_blob_str(blob, data.reg_expand_sz, strlen(data.reg_sz) + 1); break; case REG_BINARY: init_rpc_blob_bytes(blob, data.reg_binary.data, data.reg_binary.data_length); break; case REG_DWORD: init_rpc_blob_uint32(blob, data.reg_dword); break; case REG_DWORD_BE: init_rpc_blob_uint32(blob, data.reg_dword_be); break; case REG_MULTI_SZ: /*need to find the size*/ for(i = 0; i < data.reg_multi_sz.num_strings; i++) { size += strlen(data.reg_multi_sz.strings[i]) + 1; } /**need a whole bunch of unicode strings in a row (seperated by null characters), with an extra null-character on the end*/ multi = TALLOC_ZERO_ARRAY(mem_ctx, uint8, (size + 1)*2); /*size +1 for the extra null character*/ if(!multi) { errno = ENOMEM; break; } /*do it using rpcstr_push()*/ multi_idx = 0; for(i = 0; i < data.reg_multi_sz.num_strings; i++) { len = strlen(data.reg_multi_sz.strings[i]) + 1; rpcstr_push((multi + multi_idx), data.reg_multi_sz.strings[i], len * 2, STR_TERMINATE); /* x2 becuase it is a uint8 buffer*/ multi_idx += len * 2; } /*now initialize the buffer as binary data*/ init_rpc_blob_bytes(blob, multi, (size + 1)*2); break; default: talloc_free(blob); blob = NULL; } if(!(blob->buffer)) { talloc_free(blob); return NULL; } return blob;}/*turns a string in a uint16 array to a char array*/char *cac_unistr_to_str(TALLOC_CTX *mem_ctx, uint16 *src, int num_bytes) { char *buf; int i = 0; uint32 str_len = 0; /*don't allocate more space than we need*/ while( (str_len) < num_bytes/2 && src[str_len] != 0x0000) str_len++; /*need room for a '\0'*/ str_len++; buf = talloc_array(mem_ctx, char, str_len); if(!buf) { return NULL; } for(i = 0; i < num_bytes/2; i++) { buf[i] = ((char *)src)[2*i]; } buf[str_len - 1] = '\0'; return buf;}REG_VALUE_DATA *cac_MakeRegValueData(TALLOC_CTX *mem_ctx, uint32 data_type, REGVAL_BUFFER buf) { REG_VALUE_DATA *data; uint32 i; /*all of the following used for MULTI_SZ data*/ uint32 size = 0; uint32 len = 0; uint32 multi_idx = 0; uint32 num_strings= 0; char **strings = NULL; data = talloc(mem_ctx, REG_VALUE_DATA); if(!data) { errno = ENOMEM; return NULL; } switch (data_type) { case REG_SZ: data->reg_sz = cac_unistr_to_str(mem_ctx, buf.buffer, buf.buf_len); if(!data->reg_sz) { talloc_free(data); errno = ENOMEM; data = NULL; } break; case REG_EXPAND_SZ: data->reg_expand_sz = cac_unistr_to_str(mem_ctx, buf.buffer, buf.buf_len); if(!data->reg_expand_sz) { talloc_free(data); errno = ENOMEM; data = NULL; } break; case REG_BINARY: size = buf.buf_len; data->reg_binary.data_length = size; data->reg_binary.data = talloc_memdup(mem_ctx, buf.buffer, size); if(!data->reg_binary.data) { talloc_free(data); errno = ENOMEM; data = NULL; } break; case REG_DWORD: data->reg_dword = *((uint32 *)buf.buffer); break; case REG_DWORD_BE: data->reg_dword_be = *((uint32 *)buf.buffer); break; case REG_MULTI_SZ: size = buf.buf_len; /*find out how many strings there are. size is # of bytes and we want to work uint16*/ for(i = 0; i < (size/2 - 1); i++) { if(buf.buffer[i] == 0x0000) num_strings++; /*buffer is suppsed to be terminated with \0\0, but it might not be*/ if(buf.buffer[i] == 0x0000 && buf.buffer[i + 1] == 0x0000) break; } strings = talloc_array(mem_ctx, char *, num_strings); if(!strings) { errno = ENOMEM; talloc_free(data); break; } if(num_strings == 0) /*then our work here is done*/ break; for(i = 0; i < num_strings; i++) { /*find out how many characters are in this string*/ len = 0; /*make sure we don't go past the end of the buffer and keep looping until we have a uni \0*/ while( multi_idx + len < size/2 && buf.buffer[multi_idx + len] != 0x0000) len++; /*stay aware of the \0\0*/ len++; strings[i] = TALLOC_ZERO_ARRAY(mem_ctx, char, len); /*pull out the unicode string*/ rpcstr_pull(strings[i], (buf.buffer + multi_idx) , len, -1, STR_TERMINATE); /*keep track of where we are in the bigger array*/ multi_idx += len; } data->reg_multi_sz.num_strings = num_strings; data->reg_multi_sz.strings = strings; break; default: talloc_free(data); data = NULL; } return data;}SAM_USERINFO_CTR *cac_MakeUserInfoCtr(TALLOC_CTX *mem_ctx, CacUserInfo *info) { SAM_USERINFO_CTR *ctr = NULL; /*the flags we are 'setting'- include/passdb.h*/ uint32 flags = ACCT_USERNAME | ACCT_FULL_NAME | ACCT_PRIMARY_GID | ACCT_ADMIN_DESC | ACCT_DESCRIPTION | ACCT_HOME_DIR | ACCT_HOME_DRIVE | ACCT_LOGON_SCRIPT | ACCT_PROFILE | ACCT_WORKSTATIONS | ACCT_FLAGS; NTTIME logon_time; NTTIME logoff_time; NTTIME kickoff_time; NTTIME pass_last_set_time; NTTIME pass_can_change_time; NTTIME pass_must_change_time; UNISTR2 user_name; UNISTR2 full_name; UNISTR2 home_dir; UNISTR2 dir_drive; UNISTR2 log_scr; UNISTR2 prof_path; UNISTR2 desc; UNISTR2 wkstas; UNISTR2 mung_dial; UNISTR2 unk; ctr = talloc(mem_ctx, SAM_USERINFO_CTR); if(!ctr) return NULL; ZERO_STRUCTP(ctr->info.id23); ctr->info.id21 = talloc(mem_ctx, SAM_USER_INFO_21); if(!ctr->info.id21)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?