/** * @brief * main - the entry point in pbs_account_win.c * * @param[in] argc - argument count * @param[in] argv - argument variables. * @param[in] env - environment values. * * @return int * @retval 0 : success * @retval !=0 : error code */ main(int argc, char *argv[]) { SID *sa_sid = NULL; /* service account SID */ char sa_name[PBS_MAXHOSTNAME+UNLEN+2] = {'\0'}; /* service account name */ /* domain\user\0 */ int ret_val = 0; int c_opt = 0; int s_opt = 0; int a_opt = 0; int p_opt = 0; int R_opt = 0; int U_opt = 0; int instid_opt = 0; char service_bin_path[MAXPATHLEN+1] = {'\0'}; char service_name[MAXPATHLEN+1] = {'\0'}; int i = 0; char outputfile[MAXPATHLEN+1] = {'\0'}; char instanceName[MAXPATHLEN+1] = {'\0'}; int output_fd = -1; struct passwd *pw = NULL; char *p = NULL; winsock_init(); /*test for real deal or just version and exit*/ execution_mode(argc, argv); strcpy(exec_unamef, getlogin_full()); strcpy(exec_dname, "."); if ((p=strchr(exec_unamef, '\\'))) { *p = '\0'; strcpy(exec_dname, exec_unamef); *p = '\\'; } strcpy(sa_password, ""); strcpy(outputfile, ""); /* with no option, check only if service account exists */ if (argc == 1) { int in_domain_environment = 0; char dname[PBS_MAXHOSTNAME+1] = {'\0'}; char dctrl[PBS_MAXHOSTNAME+1] = {'\0'}; wchar_t unamew[UNLEN+1] = {'\0'}; wchar_t dctrlw[PBS_MAXHOSTNAME+1] = {'\0'}; USER_INFO_0 *ui1_ptr = NULL; NET_API_STATUS netst = 0; /* figure out the domain controller hostname (dctrl) */ /* in domain environment, */ /* domain name (dname) != domain controller hostname */ /* in standalone environment, */ /* domain name (dname) == domain controller hostname */ in_domain_environment = GetComputerDomainName(dname); strcpy(dctrl, dname); if (in_domain_environment) { char dname_a[PBS_MAXHOSTNAME+1]; get_dcinfo(dname, dname_a, dctrl); } /* convert strings to "wide" format */ mbstowcs(unamew, service_accountname, UNLEN+1); mbstowcs(dctrlw, dctrl, PBS_MAXHOSTNAME+1); netst = wrap_NetUserGetInfo(dctrlw, unamew, 1, (LPBYTE *)&ui1_ptr); if (strlen(winlog_buffer) > 0) { fprintf(stderr, "%s\n", winlog_buffer); } if (netst == NERR_UserNotFound) { fprintf(stderr, "%s not found!\n", service_accountname); if (in_domain_environment && stricmp(exec_dname, dname) != 0) { fprintf(stderr, "But no privilege to create service account %s\\%s!\n", dname, service_accountname); ret_val=2; } else { ret_val=1; } } else if ((netst == ERROR_ACCESS_DENIED) || (netst == ERROR_LOGON_FAILURE)) { fprintf(stderr, "no privilege to obtain info for service account %s\\%s!\n", dname, service_accountname); ret_val= 2; } else { fprintf(stderr, "service account is %s\\%s!\n", dname, service_accountname); ret_val = 0; } if (ui1_ptr != NULL) NetApiBufferFree(ui1_ptr); goto end_pbs_account; } i = 1; while (i < argc) { if (strcmp(argv[i], "-c") == 0) { c_opt = 1; i++; } else if (strcmp(argv[i], "--ci") == 0) { c_opt = 1; for_info_only = 1; i++; } else if (strcmp(argv[i], "-s") == 0) { s_opt = 1; i++; } else if (strcmp(argv[i], "-a") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service account name argument supplied!\n"); usage(argv[0]); exit(1); } a_opt = 1; strcpy(service_accountname, argv[i+1]); i+=2; } else if (strcmp(argv[i], "-p") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No password argument supplied!\n"); usage(argv[0]); exit(1); } p_opt = 1; strcpy(sa_password, argv[i+1]); cache_usertoken_and_homedir(service_accountname, NULL, 0, read_sa_password, (char*)service_accountname, decrypt_sa_password, 1); i+=2; } else if (strcmp(argv[i], "--reg") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service binary path given\n"); usage(argv[0]); exit(1); } R_opt = 1; strcpy(service_bin_path, argv[i+1]); i+=2; } else if (strcmp(argv[i], "--unreg") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No service binary path given\n"); usage(argv[0]); exit(1); } U_opt = 1; strcpy(service_bin_path, argv[i+1]); i+=2; } else if (strcmp(argv[i], "-o") == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No output path argument supplied!\n"); usage(argv[0]); exit(1); } p_opt = 1; strcpy(outputfile, argv[i+1]); i+=2; } else if (strncmp(argv[i], "--instid", strlen("--instid")) == 0) { if ((argv[i+1] == NULL) || (argv[i+1][0] == '-')) { fprintf(stderr, "No instance id supplied!\n"); usage(argv[0]); exit(1); } instid_opt = 1; strncpy(instanceName, argv[i+1], MAXPATHLEN); i+=2; } else { fprintf(stderr, "Unknown option %s\n", argv[i]); usage(argv[0]); exit(1); } } if (strlen(outputfile) > 0) { if ((output_fd=open(outputfile, O_RDWR|O_CREAT, 0600)) != -1) { _dup2(output_fd, 1); /* put stdout in file */ _dup2(output_fd, 2); /* put stderr in file */ } } /* prompt for password if not supplied with -p */ if ((c_opt || R_opt) && (strcmp(sa_password, "") == 0)) { prompt_to_get_password(sa_password); cache_usertoken_and_homedir(service_accountname, NULL, 0, read_sa_password, (char *)service_accountname, decrypt_sa_password, 1); } /* Need to get service_name */ if (R_opt || U_opt) { char *p = NULL; int k = 0; strcpy(service_name, service_bin_path); if ((p=strrchr(service_bin_path, '\\'))) { strcpy(service_name, p+1); } if ((p=strrchr(service_name, '.'))) {/*remove .exe portion*/ *p = '\0'; } /* translate from lower-case to upper-case */ for (k=0; k < strlen(service_name); k++) { service_name[k] = toupper(service_name[k]); } if (instid_opt) { strcat_s(service_name, MAXPATHLEN, "_"); strcat_s(service_name, MAXPATHLEN, instanceName); } } if (c_opt) { if (add_service_account(sa_password) == 0) { ret_val = 3; goto end_pbs_account; } } if (s_opt || R_opt) { /* need service account name */ sa_sid = getusersid2(service_accountname, sa_name); if (sa_sid == NULL) { fprintf(stderr, "%s not found!\n", service_accountname); ret_val= 1; goto end_pbs_account; } if (!isAdminPrivilege(service_accountname)) { fprintf(stderr, "%s is not ADMIN! - %s\n", service_accountname, winlog_buffer); ret_val = 2; goto end_pbs_account; } } if (s_opt) { int r1, r2, r3, r4; printf("Setting the following privileges to %s:\n", sa_name); r1 = add_privilege(sa_sid, SE_CREATE_TOKEN_NAME); r2 = add_privilege(sa_sid, SE_ASSIGNPRIMARYTOKEN_NAME); r3 = add_privilege(sa_sid, SE_SERVICE_LOGON_NAME); r4 = add_privilege(sa_sid, SE_TCB_NAME); if ((r1 != 0) || (r2 != 0) || (r3 != 0) || (r4 != 0)) { ret_val = 4; goto end_pbs_account; } } if (R_opt) { ret_val = register_scm(__TEXT(service_name), service_bin_path, sa_name, sa_password); } if (U_opt) { ret_val = unregister_scm(__TEXT(service_name)); } end_pbs_account: if (sa_sid != NULL) LocalFree(sa_sid); if (strlen(sa_password) > 0) memset((char *)sa_password, 0, strlen(sa_password)); if (output_fd != -1) (void)close(output_fd); exit(ret_val); }
int perm_granted(char *path, int perm_mask, char *user, char *realuser) { int rc; DWORD i, j; ACL *pdacl = NULL; SECURITY_DESCRIPTOR *psd = NULL; ACL_SIZE_INFORMATION sizeInfo; ACCESS_ALLOWED_ACE *pace; struct accessinfo *allowed = NULL; struct accessinfo *denied = NULL; int mask; char *name; SID *usid; if (GetNamedSecurityInfo(path, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, 0, 0, &pdacl, 0, &psd) != ERROR_SUCCESS) { errno = GetLastError(); rc = 1; goto perm_chkerr; } usid = getusersid2(user, realuser); if (usid == NULL) { rc = 2; goto perm_chkerr; } /* make sure perm mask granted only to privilege groups or the special 'owner' */ GetAclInformation(pdacl, &sizeInfo, sizeof(sizeInfo), AclSizeInformation); allowed = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); denied = (struct accessinfo *)malloc(sizeof(struct accessinfo)*sizeInfo.AceCount); if (allowed == NULL || denied == NULL) { rc = 3; goto perm_chkerr; } accessinfo_init(allowed, sizeInfo.AceCount); accessinfo_init(denied, sizeInfo.AceCount); for (i=0; i < sizeInfo.AceCount; i++) { GetAce(pdacl, i, (void **)&pace); name = getgrpname_full((SID *)&pace->SidStart); if (name == NULL) name = getusername((SID *)&pace->SidStart); /* later, we need to also check denied access which */ /* overrides allowed access. */ if ( (pace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) && \ (mask=(pace->Mask & perm_mask)) && \ EqualSid((SID *)&pace->SidStart, usid) ) { (void)accessinfo_add(allowed, sizeInfo.AceCount, name, (mask & 0xFFFF)); } else if (pace->Header.AceType == ACCESS_DENIED_ACE_TYPE) { (void)accessinfo_add(denied, sizeInfo.AceCount, name, (pace->Mask & 0xFFFF)); } else { if (name) { (void)free(name); } } } /* filter the allowed pool so that none appear in denied */ for (i=0; i < sizeInfo.AceCount; i++) { for (j=0; j < sizeInfo.AceCount; j++) { if( allowed[i].group == NULL || \ denied[j].group == NULL ) continue; if (strcmp(allowed[i].group, denied[j].group) == 0) allowed[i].mask &= ~denied[j].mask; /* unset the denied mask from allowed */ } } /* now filter perm_mask to those specified in allowed */ for (i=0; i < sizeInfo.AceCount; i++) { if (allowed[i].group == NULL) continue; /* unset the allowed mask from perm_mask */ perm_mask &= ~allowed[i].mask; } if (perm_mask != 0) { rc = 4; goto perm_chkerr; } rc = 0; perm_chkerr: if (pdacl) LocalFree(pdacl); if (psd) LocalFree(psd); if (allowed) accessinfo_free(allowed, sizeInfo.AceCount); if (denied) accessinfo_free(denied, sizeInfo.AceCount); if (usid) LocalFree(usid); return (rc); }